任何人都可以帮助我解决我的困境吗?当我编译我的程序时,我没有得到任何错误或警告。但是,当我去实际运行可执行文件时,我得到了分段错误。如果我理解正确,就会发生这种情况,因为错误地使用了指针。我在feof(srcIn)行上得到一个特定的错误,我不知道为什么。除了程序开头的srcIn = fopen(argv [0],“r”)值之外,永远不会为FILE * srcIn分配新值。我最初使用C ++实现了这个解决方案,并且需要将其更改为C。无论如何,在C ++中,除了使用srcIn.eof()作为条件并使用srcIn.get(something)作为读取方法之外,我基本上做了相同的事情。它编译并运行没有任何问题。
int chara;
int line[maxLineLength+1];
void nextch(void){
const int charPerTab = 8;
if(charCounter == charLineCounter){
if(feof(srcIn)){
printf("\n");
isEOF = TRUE;
return;
}
printf("\n"); lineCounter++;
if(chara != '\0'){ printf("%c", line[charLineCounter-1]); } // first character each line after the first line will be skipped otherwise
charLineCounter = 0; charCounter = 0;
while(chara != '\n'){
chara = fgetc(srcIn);
if(chara >= ' '){
printf("%c", chara);
line[charLineCounter] = chara; charLineCounter++;
}
else if(chara == '\t'){ // add blanks to next tab
do{ printf(" "); line[charLineCounter] = ' '; charLineCounter++; }
while(charLineCounter % charPerTab != 1);
}
}
printf("\n"); line[charLineCounter] = chara; charLineCounter++; line[charLineCounter] = fgetc(srcIn); charLineCounter++;
// have to get the next character otherwise it will be skipped
}
chara = line[charCounter]; charCounter++;
}
编辑:
我忘了提到我在遇到seg故障时甚至没有真正进入主流。这让我相信可执行文件本身存在某种问题。 gdb告诉我seg错误发生在行:
if(feof(srcIn))
有什么想法吗?
答案 0 :(得分:2)
我怀疑你的两个或四个字符的缩进不足以让你看到程序的真实范围;它可能就像@mu太短而且@Null Set指出的那样简单,当你的意思是argv[0]
时你得到argv[1]
,它可能就像@Lou Franco指出的那样你'写完你的数组的结尾,但这段代码确实闻起来很有趣。这是您的代码,通过Lindent
运行以获得更大的标签和每行一个语句:
int chara;
int line[maxLineLength + 1];
void nextch(void)
{
const int charPerTab = 8;
if (charCounter == charLineCounter) {
if (feof(srcIn)) {
printf("\n");
isEOF = TRUE;
return;
}
printf("\n");
lineCounter++;
if (chara != '\0') {
printf("%c", line[charLineCounter - 1]);
} // first character each line after the first line will be skipped otherwise
charLineCounter = 0;
charCounter = 0;
while (chara != '\n') {
chara = fgetc(srcIn);
if (chara >= ' ') {
printf("%c", chara);
line[charLineCounter] = chara;
charLineCounter++;
} else if (chara == '\t') { // add blanks to next tab
do {
printf(" ");
line[charLineCounter] = ' ';
charLineCounter++;
}
while (charLineCounter % charPerTab != 1);
}
}
printf("\n");
line[charLineCounter] = chara;
charLineCounter++;
line[charLineCounter] = fgetc(srcIn);
charLineCounter++;
// have to get the next character otherwise it will be skipped
}
chara = line[charCounter];
charCounter++;
}
您正在if
语句中检查是否已在顶部的文件末尾读取,但您再也不会检查eof
。决不。当您从while()
循环中的输入中读取时,使用'\n'
作为退出条件,如果字符高于' '
则打印输出,如果您读取{{{},请执行一些制表符展开1}},您忘记处理来自'\t'
的{{1}}返回。如果您的输入文件没有EOF
,则此程序可能会将fgetc(3)
写入'\n'
数组,直到您出现段错误。如果您的输入文件没有直接在-1
上结束,那么此程序可能会将line
写入'\n'
数组,直到您发生段错误。
从输入流中读取一个字符并对其进行操作的大多数循环都是这样写的:
-1
检查line
的输入。如果可以的话,只从一个地方读取输入。使用一个表或int c;
FILE *f = fopen("foo", "r");
if (!f) {
/* error message if appropriate */
return;
}
while ((c=fgetc(f)) != EOF) {
if (' ' < c) {
putchar(c);
line[counter++] = c;
} else if ('\t' == c) {
/* complex tab code */
} else if ('\n' == c) {
putchar('\n');
line[counter++] = c;
}
}
/ EOF
/ if
/ else if
树来决定如何处理输入字符。最初使用else if
成语可能不自然,但在C中很常见。
随意为您自己的代码窃取我建议的循环格式,并弹出复杂的标签扩展代码。看起来你做对了,但我对此并不积极,我不希望它分散注意力循环的整体风格。我认为你会发现扩展我的代码来解决你的问题比让你的工作更容易。 (我完全希望你可以,但我认为维护它并不好玩。)
答案 1 :(得分:1)
argv[0]
是您的计划的名称,因此您的fopen(argv[0], 'r')
可能会失败。我猜你想要打开argv[1]
。当然,在尝试使用其返回值之前,请检查fopen
是否成功。
答案 2 :(得分:1)
它可能不在这个功能中,但如果问题出现在这里,我最担心的是在线超出界限。你写的不仅仅是maxLineLength
个字符吗?您应该在进行索引之前进行检查。
编辑:您似乎对这个错误甚至意味着什么感到困惑 - 我会尝试清理它。
当您遇到分段错误时,它所发生的行就是最终检测到内存已损坏的代码行。它不一定与真正的问题有任何关系。你需要做的是首先找出腐败发生的地方。
很常见的原因:
还有很多其他方法。
解决这个问题的关键是
答案 3 :(得分:1)
它可能应该是srcIn = fopen(argv[1], "r")
。 main获取的0
字符串参数通常是程序的名称,1
st参数是您传递给程序的第一个命令行参数。