проблема fscanf с чтением в Строке

Самый легкий путь состоит в том, чтобы, вероятно, только использовать list(), но также существует, по крайней мере, еще одна опция:

s = "Word to Split"
wordlist = list(s)               # option 1, 
wordlist = [ch for ch in s]      # option 2, list comprehension.

Они должны оба , дают Вам, в чем Вы нуждаетесь:

['W','o','r','d',' ','t','o',' ','S','p','l','i','t']

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

[doSomethingWith(ch) for ch in s]
5
задан jumm 12 December 2009 в 15:09
поделиться

5 ответов

Jumm wrote:

If I use fgets in the place of the fscanf above I get "\n" in the variable.

Which is a far easier problem to solve so go with it:

fgets( ap->name, MAX, fp ) ;
nlptr = strrchr ( ap->name, '\n' ) ;
if( nlptr != 0 )
{
    *nlptr = '\0' ;
}
2
ответ дан 18 December 2019 в 14:47
поделиться

Одна из проблем:

result = fscanf(fp, "%[^\n]s", ap->name);

состоит в том, что у вас есть лишние s в конце спецификатора формата. Полный спецификатор формата должен иметь вид % [^ \ n] , что означает «читать в строке, состоящей из символов, не являющихся символами новой строки». Дополнительные s не являются частью спецификатора формата, поэтому они интерпретируются как литерал: «прочитать следующий символ из ввода; если это« s », продолжить, иначе - сбой».

extra s на самом деле вам не повредит. Вы точно знаете, какой следующий символ ввода: новая строка. Он не совпадает, и обработка ввода останавливается на этом, но это не имеет особого значения, поскольку это конец вашего спецификатора формата. Однако это вызовет проблемы, если у вас были другие спецификаторы формата после этого в той же строке формата.

Настоящая проблема в том, что вы не используете новую строку: вы читаете только все символы с до , новая строка, но не сама новая строка. Чтобы исправить это, вы должны сделать следующее:

result = fscanf(fp, "%[^\n]%*c", ap->name);

Спецификатор % * c предписывает читать символ ( c ), но не присваивать его какой-либо переменной ( * ). Если вы пропустили * , вам нужно будет передать fscanf () другой параметр, содержащий указатель на символ ( char * ), где он будет сохранить получившийся символ, в котором он читал.

Вы также можете использовать % [^ \ n] \ n , но это также будет читаться в любых пробелах, следующих за новой строкой, что может быть не тем, что вы хочу. Когда fscanf находит пробелы в своем описателе формата (пробел, новая строка или табуляция), он использует столько пробелов, сколько может (т. Е. Вы можете представить себе, что он использует самую длинную строку, которая соответствует регулярному выражению ] [\ t \ n] * ).

Наконец, вы также должны указать максимальную длину, чтобы избежать переполнения буфера. Вы можете сделать это, поместив длину буфера между % и [. Например, если ap-> name является буфером из 256 символов, вы должны сделать это:

result = fscanf(fp, "%255[^\n]%*c", ap->name);

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

char format[256];
snprintf(format, sizeof(format), "%%%d[^\n]%%*c", buffer_size - 1);
result = fscanf(fp, format, ap->name);
12
ответ дан 18 December 2019 в 14:47
поделиться

I'm not sure how you mean [^\n] is suppose to work. [] is a modifier which says "accept one character except any of the characters which is inside this block". The ^ inverts the condition. %s with fscanf only reads until it comes across a delimiter. For strings with spaces and newlines in them, use a combination of fgets and sscanf instead, and specify a restriction on the length.

0
ответ дан 18 December 2019 в 14:47
поделиться

There is no such thing as I gather you are trying to imply a regular expression in the fscanf function which does not exist, not that to my knowledge nor have I seen it anywhere - enlighten me on this.

The format specifier for reading a string is %s, it could be that you need to do it this way, %s\n which will pick up the newline.

But for pete's sake do not use the standard old gets family functions as specified by Clifford's answer above as that is where buffer overflows happen and was used in a infamous worm of the 1990's - the Morris Worm, more specifically in the fingerd daemon, that used to call gets that caused chaos. Fortunately, now, that has now been patched. And furthermore, a lot of programmers have been drilled into the mentality not to use the function.

Even Microsoft has adopted a safe version of gets family of functions, that specifies a parameter to indicate the length of buffer instead.

EDIT My bad - I did not realize that Clifford indeed has specified the max length for input...Whoops! Sorry! Clifford's answer is correct! So +1 to Clifford's answer.

Thanks Neil for pointing out my error...

Hope this helps, Best regards, Tom.

0
ответ дан 18 December 2019 в 14:47
поделиться

Я обнаружил проблему.

Как сказал Пол Томблин, у меня был дополнительный символ новой строки в поле выше. Итак, используя то, что сказал tommieb75, я использовал:

result = fscanf(fp, "%s\n", ap->code);
result = fscanf(fp, "%[^\n]s", ap->name);

И это исправило!

Спасибо за вашу помощь.

-1
ответ дан 18 December 2019 в 14:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: