0

我正在尝试用 C 编写一个程序来检测 CSV 格式,例如。十进制commadecimal。并给出文件是否为所需格式的输出。我尝试使用来自标准输入的各种输入并使用 isdigit 等,但没有成功。我是一个超级菜鸟,之前几乎没有做过任何 C 编程,我尝试使用 regexc 但无法弄清楚使用它的语法。

#include <ctype.h>
#include <stdio.h>
const char EOL = '\n';

int cbreak(void);
int check_dig(void);
int value =1;
char c;

int main()
{

    while((scanf("%c" ,&c)) !=EOF&& value !=0)
    check_dig();

    printf("\n%d\n",value);
}

int check_dig()
{
    if (c == EOL)
        scanf("%c", &c);
    if (c == isdigit)
        scanf("%c", &c);
    else if (c == ',')
        scanf("%c", &c);
    else value = 0;
}

谢谢伙计们,我现在到了这个阶段,但是对于如何完成感到困惑,我需要根据验证打印 1 或 0,我想按照建议使用返回值来执行此操作。

#include <ctype.h>
#include <stdio.h>

int check_digit(int);
int check_comma(int);
int skip_char(int);
int main()
{
    int c;

    while ((c = getchar()) !=EOF)
        if (check_digit(c))
            skip_char(c);
        else if (check_comma(c))
            skip_char(c);
        else return 0;
}

int check_digit(int c)
{   
    if (isdigit(c))
        return 1;
    else return 0;
}    

int check_comma(int c)
{
    if (c == ',')
        return 1;
    else return 0;
}

int skip_char(int c)
{
    c = getchar(); // will this skip 2 chars as i have a while loop that has c=getchar()??
    return c;
}
4

2 回答 2

0

我不建议使用 regexc 来解决这个问题,特别是如果您是 C 新手。您应该能够使用一些基本的标准库功能来解决它​​。你似乎在正确的一般轨道上。您正在阅读字符并确定它们适合什么类。由于您知道有效输入仅包含数字和逗号字符,因此如果遇到不属于这两种情况之一的任何内容,您可以立即终止程序。这里有一些可能会有所帮助的提示。

如果您一次读取一个字符,getchar可能会比scanf.

另外,isdigit是一个函数。与其说,不如if (c == isdigit)if (isdigit(c))

您的函数check_dig被定义为返回一个int,但return函数中没有语句。该函数需要修改以返回一个值,并且main需要对这个值做一些事情。一般的经验法则是,函数在成功完成时返回零,或者在出错时返回非零。在您的情况下,“成功”可能表示“字符有效”,“错误”可能表示“字符无效”。进行此更改应该可以消除全局变量valuec如果您将输入check_dig作为参数传递给,您也可以消除全局变量(c将成为内部的局部变量main())。

我建议您只使用该check_dig功能来检查数字,并删除读取另一个字符的部分。您应该在调用 之前决定是否跳过一个字符check_dig。这样,您可以将“读取”代码、“跳过”代码和“检查”代码分开。这使您的程序更易于阅读和调试。

于 2012-04-13T01:07:58.810 回答
0

首先,我建议不要使用大量的全局变量。在函数中使用参数并从函数返回值。

第二个isdigit不是那样工作的。它接受一个参数并返回真或假。是数字

此外,我会在 scanf 上使用getchar 。

你的int check_dig()功能有点奇怪。您继续阅读函数内部的字符。

我可能会做类似的事情:

int valid_csv(char c)
{
    if (isdigit(c))
        return 1;
    /* etc. other checks */
    if all fails
    return 0;
}

int main(void)
{
    int c;

    /* read chars into c and call fun by something like */
    valid_svc(c);

    return 0;
}

编辑:根据经验。一个函数应该做一件事,而且只做一件事,并且把它做好。函数的名称应该反映它的作用。


编辑2:

您不需要“跳过字符”。在您的新代码中,它的方式是跳过所有其他字符。

IE:

文件:12、33、66、14

在您的代码中,您将获得

  • c = getchar => c == 1
  • c是数字
    • getchar => 你读了 2 (并且从不验证它)
  • c = getchar => c == ,
  • c 是逗号
    • getchar => 你读了 3 (并且从不验证它)
  • ...

更远; 我知道我写了“一个函数应该做一件事”——但不是那个字面意思。即你的新check_digit是多余的。直接使用isdigit。如果您的 csv 中有浮点数,则必须扩展或使用不同的方法。

举例说明;然后在这里写更容易:)

#include <ctype.h>
#include <stdio.h>

int valid_csv_chr(int);
int valid_csv(); /* guess naming could be better. */

int main(void)
{
    if (valid_csv())
        puts("1");
    else
        puts("0");

    return 0; /* Main should return 0 if there was no "crash" scenario etc.
     * You could also return i.e. 1 if the file is not validated as csv. 
     * Do not think of 1 and 0 as boolean true / false here. */
}

int valid_csv()
{
    int c;

    while((c = getchar()) !=EOF) {
        if (!valid_csv_chr(c)) {
            return 0;
        }
    }

    return 1;
}

int valid_csv_chr(int c)
{
    if (isdigit(c))
        return 1;
    if (c == ',')
        return 1;
    if (c == '\n')
        return 1;
        /* add checks for space etc. */
    return 0;
}

编辑3:

代码结构与语言本身一样需要学习。它是边做边写的学习。人们意识到代码的重新结构是必要的,但在编写之前考虑得越多,首先制作一个简单的结构并扩展它等等。它是更可以避免的。

无论如何; 练习,练习,练习。并始终牢记这些主题。

即使它可以“看起来”简单,但事实并非如此。我认为通常书籍、教程、课程等都很少关注这个主题。它完全是关于for, , 函数等的,几乎没有关于如何以一种好的方式if将它们拼接在一起。

拆分代码有几个优点。

  • 它使它更具可读性。
  • 它使维护变得更容易。
  • 错误和错误通常可以通过修复一个小功能而不是一个大功能来修复。
    • 在某些情况下,我看到了数千行代码,其中一个具有一些错误的怪物功能。通过调整来修复它几乎是不可能的,完全重写是唯一的选择。
  • 优化执行一项任务且规模不大的功能更容易。
  • 当使用较小的功能时,更容易扩展以覆盖更多场景。
    • 例如在你的程序中说。您可以将其更改为“验证数据文件”,包括 csv、制表符分隔、对齐等。

最后一点其实是我写作时经常想到的一种方式;“我应该如何最好地实现此代码,以便将来如果我想扩展它以涵盖更多场景,则可以轻松完成。”

我自己在用 C 语言编写时,结合我在 K&R 的 ANSI C 书 ++ 中学到的东西,以此基础。例如,参见关于函数的内容。

还; 严格的编码风格使它更容易阅读和维护。我在很大程度上使用了上面文档中描述的内容。这不是法律,但意识到这一点会使编码生活变得如此简单。

于 2012-04-13T01:04:09.963 回答