У меня навязчивое подозрение, что ваших двух-или четырехсимвольных отступов недостаточно, чтобы вы могли увидеть реальный объем программы; это может быть так же просто, как @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'
в качестве условия выхода, печатаете вывод, если символ выше ' '
, делаете некоторое расширение табуляции, если вы читаете '\t'
, и вы забыли обработать EOF
возврат от fgetc(3)
. Если ваш входной файл не имеет '\n'
, то эта программа, вероятно, будет записывать -1
в ваш массив line
до тех пор, пока вы не перейдете в segfault. Если ваш входной файл не заканчивается непосредственно на '\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
/ else
дерево, чтобы решить, что делать с вашим вводимым символом. Поначалу идиома array[index++] = value;
может быть не совсем естественной, но в C.
это часто встречается.
Не стесняйтесь красть мой предложенный формат цикла для вашего собственного кода и вставлять код расширения сложной вкладки. Похоже, вы поняли это правильно, но я не уверен в этом, и я не хотел, чтобы это отвлекало от общего стиля цикла. Я думаю, вы найдете, что расширить мой код для решения вашей проблемы проще, чем заставить работать ваш. (Я полностью ожидаю, что вы можете , но я не думаю, что было бы весело поддерживать.)