Я часами ломал голову над тем, почему это не работает.
#include <stdio.h>
#define MAXLINE 1000
#define TRUE 1
#define FALSE 0
int getLine(char s[], int lim);
void copy(char to[], char from[]);
void add(char to[], char from[], int max);
int main(){
int len;
int max;
char line[MAXLINE];
char longest[MAXLINE];
max = 0;
len = 0;
while(( len = getLine(line, MAXLINE)) > 0){
if (max == len){
add(longest, line, max);
}
if (len > max){
max = len;
copy(longest, line);
}
}
if (max > 0){
printf("%s", longest);
}
return 0;
}
int getLine(char s[], int lim){
int c, i;
for (int state = FALSE, i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n';){
if (c == '\t' || c == ' ' && state == TRUE)
continue;
if (c == '\t' || c == ' '){
s[i] = c;
++i;
state = TRUE;
} else {
s[i] = c;
state = FALSE;
++i;
}
}
if (c == '\n'){
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
void copy(char to[], char from[]){
int i = 0;
while((to[i] = from[i]) != '\0'){
++i;
}
}
void add(char to[], char from[], int max){
if (max != 0){
int control = max * 2;
to[max] = from[0];
++max;
for(int i = 1; max <= control; ++max, ++i ){
to[max] = from[i];
};
};
}
Я что-то пропустил ? Я запустил valgrind с такими результатами
==22786== Memcheck, детектор ошибок памяти
==22786== Авторские права (C) 2002–2017 гг. и лицензия GNU GPL, Джулиан Сьюард и др.
==22786== Использование Valgrind-3.18.1 и LibVEX; повторите запуск с -h для получения информации об авторских правах
==22786== Команда: ./maxLine
==22786==
как
==22786== Использование неинициализированного значения размера 8.
==22786== по адресу 0x10933A: getLine
==22786== по 0x109230: основной
==22786==
==22786== Использование неинициализированного значения размера 8.
==22786== по адресу 0x10934D: getLine
==22786== по 0x109230: основной
==22786==
==22786== Условный переход или перемещение зависит от неинициализированных значений.
==22786== по адресу 0x10923E: основной
==22786==
==22786== Условный переход или перемещение зависит от неинициализированных значений.
==22786== по адресу 0x1091C9: основной
==22786==
==22786== Условный переход или перемещение зависит от неинициализированных значений.
==22786== по адресу 0x1091F6: основной
==22786==
==22786== Условный переход или перемещение зависит от неинициализированных значений.
==22786== по адресу 0x109396: скопировать
==22786== по 0x10921C: основной
==22786==
В БДБ:
[Отладка потоков с использованием libthread_db включена]
Использование хост-библиотеки libthread_db "/lib/x86_64-linux-gnu/libthread_db.so.1".
как
Программа получила сигнал SIGSEGV, ошибка сегментации.
0x000055555555533a в getLine (s=0x7ffffffd7e0 "as\377\367\377\177", lim=1000) в maxLine.c:53
53 с[и] = с;
(gdb) обратная трассировка
#0 0x000055555555533a в getLine (s=0x7ffffffd7e0 "as\377\367\377\177", lim=1000) в maxLine.c:53
#1 0x0000555555555231 в main() в maxLine.c:18
Я не знаю, с чего начать
При запросе помощи по отладке предоставьте минимально воспроизводимый пример, включая точную копию входных данных, воспроизводящих проблему. «Любой вход» — неподходящее описание. Возможно, вы пробовали различные значения для некоторых форм ввода, подходящих для программы, но кто-то, кто впервые обращается к вашей программе, может не знать, какая форма ввода подходит для программы. А наличие конкретного конкретного примера помогает отладке и общению о программе.
valgrind и gdb будут более полезны, если вы перекомпилируете программу, добавив -g -Og
в командную строку.
В getline
for (int state = FALSE, i = 0; …
объявляет i
, который существует только во время выполнения оператора for
. Значение i
, объявленное ранее в подпрограмме, не затрагивается. Тот, что раньше i
, не инициализирован. Тот, что раньше, i
используется позже в подпрограмме без инициализации.
Большинство компиляторов диагностируют это. Компилируйте с включенными предупреждениями и повышенным уровнем ошибок. В Clang начните с -Wmost -Werror
. При использовании GCC начните с -Wall -Werror
. В MSVC начните с /W3 /WX
.
Могут быть и другие ошибки в программе.
Еще одно примечание, в дополнение к данному ответу: похоже, что
c == '\t' || c == ' ' && state == TRUE
вы можете добавить круглые скобки, чтобы зафиксировать приоритет, если вы хотите, чтобыSTATE
соответствовало и вкладкам.