Давайте рассмотрим одну из проблем.
зло strncpy
Код использует strncpy
с магическим числом 4. Это не гарантирует, что spl[x]
является строкой , поскольку у символов может отсутствовать конечный нулевой символ .
strncpy(spl[x], dspl, 4); // Avoid code like this
Более поздний код пытается напечатать string с "%s"
и spl[z]
и получает "cardgene ...", а не ожидаемую "карточку".Если spl[z]
не является строкой, результатом будет неопределенное поведение (UB) - может произойти что угодно.
// Alternative: could limit output with
snprintf(line, sizeof(line),"%.*s\n",(int) (sizeof spl[z]), spl[z]);
Как исправить?
Не используйте sscanf(line,"%s",&dspl);
, поскольку в нем отсутствует ограничение ширины, или неизвестно, что dspl
примерно такого же размера, как line
.Я ожидаю
char dspl[4+1];
sscanf(line,"%4s", dspl);
Лучше убедиться, что исходной строки и массива назначения достаточно, чем использовать strncpy()
без тестов.
char spl[X_N][4+1];
char dspl[sizeof spl[0]];
// strncpy(spl[x], dspl, 4);
strcpy(spl[x], dspl);
Другие исправления включают в себя уверенность в sscanf()
завершено, как ожидалось.Простой подход использует " %n"
для записи смещения сканирования, если оно зашло так далеко, а затем ищет лишний мусор.Ненужное "\t"
удалено.
// Insure dname is at least 50+1, dspl is 4+1 or as big as the line
char dname[sizeof line];
char dspl[sizeof line];
// sscanf(line,"%d\t%s\t%s\t%d\t%d\t%d",&dno,&dname,&dspl,&ti1,&ti2,&ti3);
int n = 0;
sscanf(line,"%d%50s%4s%d%d%d %n",&dno,dname,dspl,&ti1,&ti2,&ti3, &n);
if (n==0 || line[n]) {
puts("Bad Input"); // Handle bad input in some fashion
exit(RETURN_FAILURE);
}