我正在编写一个Unix expand
实用程序的版本,它用文件中的空格替换制表符。为此,我正在阅读每个角色并测试它是否是制表符。如果是,它将使用给定的空格量替换选项卡,否则将打印该字符。
我的主要方法就像
int main(int argc, char *argv[]){
FILE *fp;
char *help1="-help";
char *help2= "--help";
//int spaces; //number of spaces to replace tabs
fp= fopen(argv[1], "rw");
parse_file(fp, 4);
fclose(fp);
return 0;
}
parse_file方法就像
void parse_file(FILE *fp, int spaces)
{
int i; //loop counter
char c; //current character
while (c!= EOF)
{
c= getchar(); //get char from stream
if (c=='\t') //if char is a tab
{
for (i=0; i< spaces; i++)
putchar(" "); //replace with spaces
}
else
putchar(c); //otherwise, print the character
}
}
编译时,我从指针获得一个整数而没有putchar(" ");
的强制警告,程序在执行时会遇到段错误。
所以,我的问题:
1-什么是警告“从没有强制转换的指针生成整数”这一切?我该怎么做才能解决它?
2-代码在执行时生成段错误,文本文件作为参数传入。这段代码中有什么东西可以导致这种情况吗?
答案 0 :(得分:8)
你必须使用
putchar(' ')
代替
putchar(" ")
答案 1 :(得分:5)
您在字符串(putchar
)上调用" "
,但它需要char
参数(' '
)。 (实际上是int
,但只传递char
是安全的。)
段错误可能是由fclose
fp
引起的,NULL
可能是fopen
。您应该检查parse_file
的返回值。您在fp
之后才注意到的原因是它根本没有触及stdin
(它从stdout
读取并写入fp
)。要使用流getc(fp)
,您应该使用putc(fp)
和fopen
代替。 (这仍然无效,因为你用比你从中读取数据更多的数据覆盖流,所以你会把垃圾丢弃。)
实际上,当没有给出命令行参数时,程序肯定会出现段错误。 argv[1]
段错误,因为它是空指针stdin
,或者它本身返回一个空指针。
在编写这些类型的程序时,请遵循Unix哲学并将其写为filters:从stdout
读取,写入{{1}}。如果不需要,请不要就地修改文件。
答案 2 :(得分:4)
在C字符串文字中,类型为char *
,指向包含字符串字符的某个区域的指针。
" "
是字符串文字,而不是字符。需要单个字符时使用' '
答案 3 :(得分:1)
正如其他人所说,重新。 char与字符串的使用。至于您看到的实际错误消息背后的逻辑,字符串是指向const数组字符的指针。因此错误是说它正在将指针转换为int。大多数char函数都使用int。
答案 4 :(得分:1)
总结一下这些问题(我正在重复其他人说过的话,但是没有提到 s 5 和6 的问题到目前为止):
putchar()
不会将字符串指针作为参数,而是一个int - 常量' '
是可接受的参数argc > 1
argv[1]
fopen()
是否已成功打开文件c
应定义为int
,因为在某些字符集中(char) -1
(0xFF)是合法字符,如果{{1},则比较c == EOF
可能会失败没有符号扩展首次使用循环c
未初始化并在循环中,您还将c
视为普通字符。 C程序中的正常习惯是
EOF
您从[{1}}而不是int c;
while ((c = fgetc(fp)) != EOF)
{
// do stuff with c
}
获取字符,因此使用stdin
而不是fp
我认为这涵盖了一切。
要回答您明确的问题,当预期使用int但是您使用指针(在这种情况下fgetc()
的类型为getchar()
)时,您会收到警告“从指针生成整数而不进行强制转换”
答案 5 :(得分:0)
除了已经说过的内容之外,getchar()还返回int而不是char。 EOF是一个int常量。您需要将getchar()的结果读入int,检查EOF,如果没有找到,则将int转换为char。