如何检测用户是否插入带逗号的数据(以所需的格式)?

2024-03-24

用户以以下格式插入数据:“[NAME],[SURNAME],[INDEX]”。错误代码:
0——一切都正确加载到结构中
1 -- 未正确加载到结构(用户未使用逗号或 p->name 出错)
2 -- 仅正确加载名称
3 -- 姓名正确加载(索引出错)

struct student_t
{
    char name[20];
    char surname[40];
    int index;
};

例子:
输入:约翰·迪普
错误代码:2

输入:约翰,深,999
错误代码:0

输入:NULL //(什么都没有)
错误代码:1
... 所以我无法检测用户是否插入例如:“John,Deep”(err 2)或“John,Deep,”(err 3)或“John,”(err 2),..(结果是 err 1;或者如果一切正常,则 err 0)
我的尝试://edit1:使用这种方法的工作版本,进一步低于此方法。

char buffer[1024], *pch1, *pch2;
if (fgets(buffer,1024, stdin)!=NULL) 
{
    pch1=strchr(buffer, ',');
    pch2=strrchr(buffer, ',');

    if (pch1!=pch2 && pch1!=NULL) //detects if inserted are 2 different commas
    {
        char *name = strtok(buffer,","); // returns pointer to the beginning of the token
        if (name) {//the place where "," occurs, becomes a "NULL" character
            sscanf(name," %19s", p->name);  // skip leading spaces
            char *surname = strtok(NULL,",");
            if (surname) {
                sscanf(surname," %39s", p->surname); // skip leading spaces
                char *index = strtok(NULL,",");
                if (index) {
                    p->index = (int)strtol(index, NULL, 10);
                           } else {*err_code=3; return NULL;} //only NAME and SURNAME correctly, INDEX is loaded wrong
                         } else {*err_code=2; return NULL;} //only NAME loaded correctly
                  }
    } else  if (pch1==pch2 && pch1!=NULL) 
    {//but if there is 1 comma, input may be like: "John, Deep" so name'd be ok
            char *name = strtok(buffer,","); 
            if (name) { 
                sscanf(name," %19s", p->name);  
                char *surname = strtok(NULL,",");
                if (surname) {
                    sscanf(surname," %39s", p->surname); 
                    char *index = strtok(NULL,",");
                    if (index) {
                        p->index = (int)strtol(index, NULL, 10);
                               }else if (p->index==0||p->index==0||p->index==' ') {*err_code=2; return NULL;}
                             } 
                      } 

    } else {*err_code=1; return NULL;} //if there were 0 commas, err_code=1
}

if (p==NULL || p->name==NULL)
{
    *err_code=1;
    return NULL;
}
 if (p->surname && p->name==NULL)
{
    *err_code=2;
    return NULL;
}
//because the above "if" construction didn't work, I added another one here:
 if (p->index==NULL || p->index==0) //so if input was "John, Deep" then p->index should be NULL? 
{
    *err_code=3;
    return NULL;
}

//edit1:好的,这段代码对我有用,一切都按设想进行。然而它非常混乱,所以我会尝试在其他版本中采用和使用答案......

char buffer[1024], *pch1, *pch2;

if (fgets(buffer,1024, stdin)!=NULL) 
{
    pch1=strchr(buffer, ',');
    pch2=strrchr(buffer, ',');

    if (pch1!=pch2 && pch1!=NULL)
    {
        char *name = strtok(buffer,","); // returns pointer to the beginning of the token
        if (name) { //the place where "," is occured becomes a "NULL" character
            sscanf(name," %19s", p->name);  // skip leading spaces
            char *surname = strtok(NULL,",");
            if (surname) {
                sscanf(surname," %39[^\t\n]", p->surname); // skip leading spaces
                char *index = strtok(NULL,",");
                if (index) {
                    p->index = (int)strtol(index, NULL, 10);
                    if (p->index==0) {*err_code=3; return NULL;}
                           } //else {*err_code=3; return NULL;} //only NAME and SURNAME correctly, INDEX is loaded wrong
                         } else {*err_code=2; return NULL;} //only NAME loaded correctly
                  }
    } else  if (pch1==pch2 && pch1!=NULL)
    {
            char *name = strtok(buffer,","); // returns pointer to the beginning of the token
            if (name) { //the place where "," is occured becomes a "NULL" character
                sscanf(name," %19s", p->name);  // skip leading spaces
                char *surname = strtok(NULL,",");
                if (surname) {
                    sscanf(surname," %39[^\t\n]", p->surname); // skip leading spaces
                    char *index = strtok(NULL,",");
                    if (index) {
                        p->index = (int)strtol(index, NULL, 10);
                               } else if (p->index==0||p->index==' ') {*err_code=2; return NULL;} 
                             } else {*err_code=1; return NULL;} 
                                          } else {*err_code=2; return NULL;}

    } else {*err_code=1; return NULL;}
}

if (p==NULL || p->name==NULL)
{
    *err_code=1;
    return NULL;
}

我有一种感觉,它可以用一种完全不同的方式来完成……我会把所有的提示和答案放在心上,并尽我最大的努力去理解和学习它们。

//edit1:如果我丑陋的代码激怒了某人,我真的很乐意做一些园丁工作并剪掉一些恶魔灌木,以清理一下。我认为有些情况根本不需要它起作用......
附言。 (这是我之前问题的延续,其中输入的逗号被分配给结构:如何扫描逗号,但逗号未分配给结构? C https://stackoverflow.com/questions/51343178/how-to-scanf-commas-but-with-commas-not-assigned-to-a-structure-c但在这个主题中,我询问以一种用户输入错误的信息的方式进行操作)


如果超出范围,这里有您需要的scanf族函数可以做到这一点,因为您想去除开头或结尾的空白字符name但仍想留出空间inside一个名字。恕我直言,您应该使用专用函数进行解析。代码可以是:

/* Find a string delimited with a character from delims.
 * Blanks at the beginning or the end of the string will be trimed out
 * At return, *end points one past the end of the string and
 * *next points after the delimiter (so delimiter will be next[-1])
 * Returns a pointer to the beginning of the string, or NULL if
 * no delimiter was found
 * */
const char* find(const char * start, char **end, char **next, const char *delims) {
    static const char blanks[] = " \t\r";
    start += strspn(start, blanks);     // trim blanks at the beginning
    *end = strpbrk(start, delims);      // search first delimiter
    if (end == NULL) {
        return NULL;
    }
    *next = *end + 1;                   // next find will start after the delimiter
    while(*end > start) {               // trim blanks at the end
        bool found = false;
        for (int i=0; i<sizeof(blanks); i++) {
            if ((*end)[-1] == blanks[i]) {
                --*end ;
                found = true;
                break;
            }
        }
        if (! found) break;
    }
    return start;
}
// parse a line to fill a student_t
struct student_t* getstruct(struct student_t *p, int *err_code) {
    char buffer[1024];
    *err_code = 1;       // be prepared to worst case
    *buffer = '\0';
    if (fgets(buffer,1024, stdin)!=NULL) 
    {
        char *end, *next;
        const char delims[] = ",\r\n";
        const char *name = find(buffer, &end, &next, delims) ; // returns pointer to the beginning of the token
        if (name && (next[-1] == ',')) {  // control the delimiter
            int l = end - name;
            if (l > 19) l = 19;
            memcpy(p->name, name, l);
            p->name[l] = '\0';
            *err_code = 2;                // Ok, we have a name followed with a comma
            const char *surname = find(next, &end, &next, delims);
            if (surname && (next[-1] == ',')) { // control delimiter
                int l = end - surname;
                if (l > 19) l = 19;
                memcpy(p->surname, surname, l);
                p->surname[l] = '\0';
                *err_code = 3;            // Ok, we have a name followed with a comma
                if (*end != ',') return NULL;
                const char *index = find(next, &end, &next, delims);
                if (index) {              // no need to control the delimiter: scanf will control  
                    char dummy[2];        // that there is no non blank char after the index
                    if (1 == sscanf(index, "%d%1s", &(p->index), dummy)) {
                        *err_code = 0;
                    }
                }
            }
        }
    }
    return (*err_code == 0) ? p : NULL;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何检测用户是否插入带逗号的数据(以所需的格式)? 的相关文章

  • Excel的解析路径

    其实我想问以下问题 对于位于 目录中定义的 PATH 怎么能 我找出这些目录中的哪个 找到了 因为我需要使用 Process Run 从 C 运行 Excel 并且只需指示 Excel 即可正常工作 Windows 似乎知道在哪里可以找到它
  • 纹理映射 C++ OpenGL

    我已经阅读了相关内容 包括 Nehe 和此处的解决方案 但我找不到具体的答案 我正在尝试加载一张名为stars jpg 的照片 我想通过使用 uv 坐标映射它来使其成为场景的背景 方法是 glBegin GL QUADS glTexCoor
  • 如何通过实体键添加/删除与实体框架的多对多关系?

    I tried using Entities e new Entities EntityKey key new EntityKey Entities Users UserId 20 User user new User EntityKey
  • 如何正确实现带有 close 方法的处置模式(CA1063)

    框架设计指南 第二版 第 327 页 说 考虑提供方法Close 除了Dispose 如果接近 是该领域的标准术语 这样做时 重要的是使 Close 实现与Dispose并考虑实施IDisposable Dispose方法明确 因此 按照提
  • 如何有效地左填充字节数组

    假设我有一个数组 LogoDataBy byte 0x00000008 0x00000000 0x41 0x00000001 0x42 0x00000002 0x43 0x00000003 0x44 0x00000004 0x31 0x00
  • 用于轻松动态反射的 C# 库

    是否有任何库 例如开源项目等 可以更轻松地使用复杂的反射 例如动态创建对象或类 检查实例等 Thanks 有一个LinFu http www codeproject com KB cs LinFuPart1 aspx可用的库除了反射之外还可
  • 会员提供商使用还是不使用?

    我正在开发一个使用 Facebook 的网站 现在为了管理用户我想使用MembershipProvider并选择开发一个定制的会员提供商 我的问题是我的数据库架构与标准成员资格架构不匹配 并且提供的用于覆盖的函数采用与我预期不同的参数 例如
  • DataGridView小数不排序

    好吧 我有一个 DataGridView 它的数据绑定如下 dataGridViewChartOre AutoGenerateColumns false dataGridViewChartOre DataSource xml GetOreC
  • C 风格强制转换与内在强制转换

    假设我已经定义了 m256d x我想提取低 128 位 我会做 m128d xlow mm256 castpd256 pd128 x 然而 我最近看到有人这样做 m128d xlow m128d x 是否有用于演员的首选方法 为什么要用第一
  • gcc 删除内联汇编代码

    看起来 gcc 4 6 2 删除了它认为函数中未使用的代码 test c int main void goto exit handler asm volatile jmp 0x0 exit return 0 拆解main 0x0804840
  • 为什么C++中没有“NULL引用”?

    我正在阅读 C 常见问题解答 8 6 什么时候应该使用引用 什么时候应该使用指针 http www parashift com c faq lite refs vs ptrs html 特别是以下声明 可以时使用引用 必要时使用指针 上述情
  • OpenMP 和 C++:this 指针

    Is thisOpenMP 中始终共享指针 尽管编译器不会抱怨以下代码default none pragma omp parallel for default none shared n for SInt i 0 i lt n i f i
  • 如何在控制台程序中获取鼠标位置?

    如何在 Windows 控制台程序中用 C 获取鼠标单击位置 点击时返回鼠标位置的变量 我想用简单的文本命令绘制一个菜单 这样当有人点击时 游戏就会注册它并知道位置 我知道如何做我需要做的一切 除了单击时获取鼠标位置 您需要使用 Conso
  • AllowUserToAddRows 不适用于 DataGridView 上的 List<> 数据源

    我有一个DataGridView与DataSource set to List
  • XSD、泛型和 C# 类的困境

    我有以下简单的 XSD 文件
  • 通过开源 PCL 使用 API 查看 3D 点云

    我使用 ToF 飞行时间 相机来获取 XYZ 格式的深度数据 为了实现 3D 点云的可视化目的 我想使用开源 PCL 提供的 API 网址为http pointclouds org documentation tutorials pcl v
  • 在 C# 中设置风扇速度

    我知道以前有人问过这个问题 但我似乎无法让它发挥作用 我已调用以下内容 using System Management using System Management Instrumentation using System Runtime
  • Image.Save 异常“GDI+ 中发生一般错误。”保存到 MemoryStream 时

    我有一个服务器客户端应用程序 我想从服务器获取屏幕截图 但在线bitmap Save ms System Drawing Imaging ImageFormat Png 我得到这个例外 A generic error occurred in
  • C++11 中引入了哪些重大更改?

    我知道 C 11 中至少有一项更改会导致一些旧代码停止编译 引入explicit operator bool 在标准库中 替换旧实例operator void 诚然 这将破坏的代码可能是一开始就不应该有效的代码 但它仍然是一个破坏性的变化
  • 创建进程的多个子进程并维护所有 PID 的共享数组

    我已经分叉了几次 并用 C 创建了一堆子进程 我想将它们所有的 PID 存储在一个共享数组中 PID 的顺序并不重要 例如 我创建了 32 个进程 我想要一个 32 个整数长的数组来存储每个 PID 并且每个进程都可以访问 最好的方法是什么

随机推荐