我正在尝试用C语言编写一个程序来检测CSV格式,例如。 decimalcommadecimal。并给出关于文件是否是所需格式的输出。我尝试过使用stdin的各种输入并使用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;
}
答案 0 :(得分:0)
首先,我建议不要使用那么庞大的全局变量列表。使用函数中的参数并从函数返回值。
第二个isdigit
不起作用。它需要一个参数并返回true或false。 isdigit
此外,我会使用getchar而不是scanf。
您的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;
}
编辑:根据经验。一个函数应该只做一件事,而且只做一件事,做得好。函数的名称应该反映它的作用。
Edit.2:
您不需要“跳过字符”。在你的新代码中,它的方式就是你跳过其他所有角色。
即:
档案:12,33,66,14
在您的代码中,您将获得
此外;我知道我写过“一个函数应该做一件事” - 但不是那个文字。即你的新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;
}
Edit.3:
代码结构是人们必须学习的东西,就像语言本身一样。它是通过实践和写作来学习的。那个人意识到必须不时地重新编写代码结构 - 但是在编写之前思考的越多,首先要做一个简单的结构并扩展它,等等。这是更容易避免的。
总之;练习,练习,练习。并始终牢记这些主题。
即使它“看起来”简单,但事实并非如此。我认为通常书籍,教程,课程等都很少关注这个主题。这完全取决于for
,if
,功能等等,而且对于如何以 良好的 方式将它们拼接在一起几乎没有。< / p>
分割代码有几个好处。
最后一点实际上是我写作时经常想到的一种方式; “我应该如何最好地实现这个代码,以便将来,如果我想扩展它以涵盖更多场景,那么可以轻松完成。”
我自己使用this作为 基础 在用C语言写作时结合我在K&amp; K中学到的东西R的ANSI C book ++。例如,请参阅有关functions的内容。
也;严格的编码风格使其更容易阅读和维护。我在很大程度上使用了上面文档中描述的内容。这不是 law ,但是有意识地使编码生活变得更加简单。
答案 1 :(得分:0)
我不建议使用regexc来解决这个问题,特别是如果你是C的新手。你应该能够使用一些基本的标准库功能解决它。你似乎在正确的轨道上。您正在阅读字符并确定它们适合哪个类。由于您知道有效输入仅包含数字和逗号字符,因此如果遇到任何不属于这两种情况的内容,您可以立即终止该程序。以下是一些可能有用的提示。
如果您一次只读一个角色,getchar
可能比scanf
更容易使用。
此外,isdigit
是一个功能。您想说if (c == isdigit)
。
if (isdigit(c))
您的函数check_dig
被定义为返回int
,但函数中没有return
语句。需要修改函数以返回值,main
需要对此值执行某些操作。一般的经验法则是函数在成功完成时返回零,或者在错误时返回非零值。在你的情况下,“成功”可能意味着“角色有效”,“错误”可能意味着“角色无效”。进行此更改应该可以消除全局变量value
。如果您将输入作为参数传递给c
,那么您也可以删除全局check_dig
(c
将成为main()
内的局部变量。)
我建议您仅使用check_dig
功能检查数字,并删除读取其他字符的部分。在调用check_dig
之前,您应该决定是否跳过一个字符。这样,您就可以分离“读取”代码,“跳过”代码和“检查”代码。这使您的程序更易于阅读和调试。