2012-02-20 4 views
-2

У меня есть два разных имен файлов, которые определены в заголовочном файле:Уменьшить длину строки в c, где ошибка?

1: "physio_sensor_readout.csv" 2: "statethresh_configuration.csv"

они инициализируются

char* filename; 

и позднее

filename = FILENAMEINAMACRO; which is the corresponding filename above 

Позже имя файла передается другой функции, которая изменяет окончание:

filename[strnlen(filename, FILENAME_LENGTH) - 4] = '\0'; 

Это должно удалить окончание .csv и i strncat новое потом. FILENAME_LENGTH - 60, поэтому достаточно места.

Он работает, если я передаю «statetresh _....» (даже strncat впоследствии), но не с «physio_se .....». Это проливает сегмент вина

strnlen(filename,FILENAME_LENGTH - 4) 

возвращает 21 в случае 1 и 25 в случае 2. это правильное положение точки, где я хочу поставить нуль-терминатор.

Это проблема с символом char *, и я должен инициализировать имя файла с именем файла char [60]?

С уважением и спасибо

редактировать:

ваши предложения решить эту проблему. благодаря!

+0

Похоже, что 'FILENAMEINAMACRO' - это, вероятно, строка с кавычками, и поэтому вы пытаетесь изменить строковый литерал, что является неопределенным поведением. Измените 'filename' на массив и используйте' strcpy' (или 'strncpy', который не является просто версией' strcpy'), чтобы вставить его. –

+0

Скорее всего, это то, что они сказали, но на всякий случай ' strnlen (filename, FILENAME_LENGTH) - 4' - это не то же самое, что 'strnlen (filename, FILENAME_LENGTH - 4)' –

+0

. Какая именно проблема здесь? Не возвращает ли функция strnlen правильные значения? – jlemos

ответ

2

Я думаю вы объявляете FILENAMEINAMACRO, как string literal [Без больше кода я не могу быть уверен, что об этом].

Строковые литералы могут быть сохранены в памяти только для чтения, поэтому вы не сможете их изменить.

В любом случае, попытка изменить строковые литералы приводит к неопределенному поведению.

Вы можете сделать копию FILENAMEINAMACRO и работать на нем с помощью strcpy()

2

Это не безопасно изменять содержимое символьного литерала. Что-то вроде этого:

char *filename = "yes"; 
filename[2] = 'p'; // change to "yep" 

не определено поведение, и может привести к катастрофическим результатам, поскольку filename может указывать на память, которая не может быть изменена. Вместо этого, попробовать что-то вроде этого:

char filename[] = "yes"; 
filename[2] = 'p'; // change to "yep" 

который выделит новый массив filename и инициализировать его содержимое "yes".

0

Вы, кажется, указываете указатель char * filename на постоянную символа. Я предполагаю, что вы определили #define FILENAMEINAMACRO "physio_sensor_readout.csv". Это делает ваше задание filename = "physio_sensor_readout.csv";. Затем вы используете указатель имени файла, чтобы изменить константу строки.Вот более подходящая последовательность:

char filename[256]; // choose a size that is suitably large 
... 
strcpy(filename, FILENAMEINAMACRO); // also look at strncpy for safer copying 
... 
... manipulate the content of filename as you wish ... 

Потому что вы сделали копию строкового литерала, изменяя это безопасно (до тех пор, пока вы остаетесь в пределах заявленного размера filename - который включает в себя сохранение любой завершение нулевого значения также в пределах.

Вы должны быть осторожны с использованием формы char filename[] = "...". Он выделяет достаточно места для строкового литерала, который вы ему даете, но если позже вы скопируете какой-либо другой строковый литерал в это пространство, вы должны быть уверены, что второй литерал уже не является первым. Более безопасная практика заключается в том, чтобы размер пространства был достаточно большим, чтобы вы были уверены, что ваш код никогда не попытается использовать больше чем то, что вы определили. Если вы принимаете ввод извне программы (или из кода другого человека), вы должны проверить длину принимаемого вами, прежде чем пытаться скопировать его в пространство, которое вы определили. Любое использование пространства за пределами размера может вызвать проблемы, которые трудно диагностировать. В приведенном выше примере вы должны приложить все усилия, чтобы вы никогда не использовали больше места (включая завершающий nul char), чем 256 символов (поскольку имя файла имеет размер 200).

Смежные вопросы