2014-08-04 2 views
0

Я ищу, чтобы скопировать первую строку с длинной строки P в буферКак скопировать одну строку из строки длиной C

Я понятия не имею, как это сделать.

while (*pros_id != '/n'){ 
    *pros_id_line=*pros_id; 
    pros_id++; 
    pros_id_line++; 
} 

И попытался

fgets(pros_id_line, sizeof(pros_id_line), pros_id); 

Оба не работают. Могу ли я помочь?

+0

вы пробовали 'strncpy'? –

+8

Новая строка '\ n' не'/n' в любом случае я бы использовал 'strchar' для этого, посмотрите на это сообщение для примера: http://stackoverflow.com/questions/10651999/how-can- i-check-if-a-single-char-exists-in-ac-string/10652031 # 10652031 –

+0

@FiddlingBits strncpy почти всегда неправильный инструмент .. в этом случае он совершенно не имеет значения. –

ответ

1

Новая линия \n не /n в любом случае я бы использовал strchar для этого:

char* endOfFirstLine = strchr(inputString, '\n'); 
if (endOfFirstLine != NULL) 
{ 
    strncpy(yourBuffer, inputString, 
     endOfFirstLine - inputString); 
} 
else // Input is one single line 
{ 
    strcpy(yourBuffer, inputString); 
} 

С inputString как вашего char* многострочной строки и inputBuffer (при условии, что это достаточно большой, чтобы содержать все данные из inputString, и это было нулевой) в качестве требуемого выхода (первая строка inputString).

+1

Нулевое окончание? 'strncpy()' не делает! –

+0

@JonathanLeffler, предположив, что он был обнулен, добавлю, что –

+2

Никогда не предполагайте, что буфер был обнулен; это пустая трата сил, все остальное. Зачем писать нули, где вы собираетесь писать информацию, и зачем писать нули, где вы не собираетесь писать информацию? –

1

Если вы собираетесь делать много чтения из длинных текстовых буферов, вы можете попробовать использовать поток памяти, если система поддерживает их: https://www.gnu.org/software/libc/manual/html_node/String-Streams.html

#define _GNU_SOURCE 
#include <stdio.h> 
#include <string.h> 

static char buffer[] = "foo\nbar"; 

int 
main() 
{ 
    char arr[100]; 
    FILE *stream; 

    stream = fmemopen(buffer, strlen(buffer), "r"); 
    fgets(arr, sizeof arr, stream); 
    printf("First line: %s\n", arr); 
    fgets(arr, sizeof arr, stream); 
    printf("Second line: %s\n", arr); 
    fclose (stream); 

    return 0; 
} 
2

Примечания как Adriano Repetti указаны в a comment и answer, что символ новой строки '\n', а не '/n'.

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

while (*pros_id != '\n' && *pros_id != '\0') 
    *pros_id_line++ = *pros_id++; 
*pros_id_line = '\0'; 

Этот код не содержит символ новой строки в скопированной буфере; достаточно легко добавить его, если вам это нужно.

Одним из преимуществ этого кода является то, что он делает один проход через данные до новой строки (или конца строки). Альтернатива делает два прохода через данные, один, чтобы найти символ новой строки, а другой, чтобы скопировать символ новой строки:

if ((end = strchr(pros_id, '\n')) != 0) 
{ 
    memmove(pros_id_line, pros_id, end - pros_id); 
    pros_id_line[end - pros_id] = '\0'; 
} 

Это гарантирует, что строка заканчивается нуль; опять же, он опускает новую строку и предполагает, что в буфере pros_id_line достаточно данных. Вы должны решить, что такое правильное поведение, когда в буфере нет новой строки. Возможно, достаточно скопировать буфер без новой строки в целевую область, или вы можете сообщить об ошибке.

Вы можете использовать strncpy() вместо memmove() но имеет более сложное условие цикла, чем memmove() - он должен проверить наличие нулевого байта, а также счета, в то время как memmove() только должен проверить счетчик. Вы можете использовать memcpy() вместо memmove(), если вы уверены, что нет никакого перекрытия между источником и целью, но memmove() всегда работает, а memcpy() иногда не работает (хотя только тогда, когда область источника и целевого объекта перекрывается), и я предпочитаю надежность над возможным неправильным поведением.

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

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

0

POSIX 2008 (например, большинство систем Linux) имеет getline(3), который содержит буфер для строки.

Таким образом, вы могли бы кодировать

FILE* fil = fopen("something.txt","r"); 
if (!fil) { perror("fopen"); exit(EXIT_FAILURE); }; 
char *linebuf=NULL; 
size_t linesiz=0; 
if (getline(&linebuf, &linesiz, fil) { 
    do_something_with(linebuf); 
} 
else { perror("getline"; exit(EXIT_FAILURE); } 

Если вы хотите, чтобы прочитать редактируемые линии от стандартного ввода в терминале рассмотреть GNU readline.

Если вы ограничены чистый код C99 вы должны сделать выделение кучи самостоятельно (malloc или calloc или, возможно, -сом realloc) Аккуратно

Если вы просто хотите, чтобы скопировать первую строку некоторого существующей буфер char*bigbuf;, который является не- NULL, действительно, и нулевые байты прекращаются:

char*line = NULL; 
char *eol = strchr(bigbuf, '\n'); 
if (!eol) { // bigbuf is a single line so duplicate it 
    line = strdup(bigbuf); 
    if (!line) { perror("strdup"); exit(EXIT_FAILURE); } 
} else { 
    size_t linesize = eol-bugbuf; 
    line = malloc(linesize+1); 
    if (!line) { perror("malloc"); exit(EXIT_FAILURE); 
    memcpy (line, bigbuf, linesize); 
    line[linesize] = '\0'; 
} 
Смежные вопросы