Есть ли другой способ обрезать строку? - PullRequest
8 голосов
/ 01 сентября 2010
char out_file_name[30];  


ogSize = strlen(FileName); //i.e. - FileName_anylength.log (always.log)
ogSize -= strlen(IN_FILE_SUFFIX); //amount of chars before .log

strncpy( out_file_name, FileName, ogSize ); //out_file_name now is FileName_anylength (without the .log)  

Это лучший способ сделать это?

Кроме того, как мне защитить, чтобы размер ogSize не превышал 30 символов, поскольку он поступает от ввода пользователя?

Спасибо.

Ответы [ 6 ]

17 голосов
/ 01 сентября 2010

С помощью строки в стиле C вы можете просто установить символ, который хотите обрезать, на \0.

Что касается вашего второго вопроса, в основном вы проверяете. Или вы выделяете столько памяти, сколько вам нужно, в зависимости от размера строки (не забудьте указать место для этого \0).

2 голосов
/ 01 сентября 2010

используйте fgets (), чтобы прочитать строку от пользователя, чтобы вы могли указать максимальную длину строки

char* from = FileName;
char* to   = out_file_name;
int curLen = 0;

do
{
  *to++=*from++
}
while(*from && *from!='.' && ++curLen < ogSize);

*to='\0';
2 голосов
/ 01 сентября 2010

Первым делом отвечая на ваш последний вопрос, обеспечить максимальный размер довольно легко. Обычно вы хотите использовать fgets для чтения строки. Это позволяет указать максимальную длину. В качестве альтернативы вы можете указать максимальный размер в формате scanf (например, "%29s" или "%29[^\n]"). Обратите внимание на разницу между ними: с помощью fgets вы указываете размер буфера, но с помощью scanf вы указываете на единицу меньше размера буфера (т. Е. Максимальное количество символов для чтения).

Что касается первого вопроса: да, как правило, есть лучшие способы. strncpy - странная функция, изначально написанная для довольно конкретной цели, и (если честно), вероятно, должна быть удалена из стандартной библиотеки, потому что, хотя кажется такой, как она должна быть полезной, она почти никогда на самом деле.

Я бы, наверное, поступил немного иначе. Одна возможность - использовать snprintf, что-то вроде:

snprintf(
    out_file_name,
    sizeof(out_file_name),
    "%*s",
    strlen(FileName) - strlen(IN_FILE_SUFFIX), FileName);
2 голосов
/ 01 сентября 2010

Дайте этот взгляд:

char *trunc;
char *outfile;

strdup( outfile, FileName );

if ( ((trunc = strstr( out_file_name, ".log" )) != NULL )
 *trunc = '\0';

return ( outfile );  // assumes returning result from function
1 голос
/ 01 сентября 2010
char out_file_name[30];
char *suffix=".log";
size_t IN_FILE_SUFFIX = strlen(suffix);

/* also works, if suffix occurs more than 1 time or never ! */
if( strstr( out_file_name, suffix ) )
  out_file_name[ strlen(out_file_name) - IN_FILE_SUFFIX ] = 0;

или

char out_file_name[30];
char *suffix=".log";
size_t IN_FILE_SUFFIX = strlen(suffix);

/* also works, if suffix occurs more than 1 time or never ! */
if( strstr( out_file_name, suffix ) )
{
  char format[20];
  sprintf( format, "%%.%ds", strlen(out_file_name) - IN_FILE_SUFFIX );
  sprintf( out_file_name, format, out_file_name );
}
1 голос
/ 01 сентября 2010

Вы можете вставить ноль в строку, чтобы сократить ее.Ниже функция strstr () используется для поиска адреса первого появления «.log».После этого вы можете вычесть два адреса друг от друга, чтобы узнать длину имени и куда вставить ноль.

int main() { 
    char suffix[] = ".log";  
    char filename[] = "FileName_anylength.log";  
    char* end_address = strstr(filename, suffix);  
    filename[end_address-filename] = 0;  
    printf("%s", filename);  
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...