Как перебрать строку в C? - PullRequest
47 голосов
/ 09 июля 2010

Прямо сейчас я пытаюсь это:

#include <stdio.h>

int main(int argc, char *argv[]) {

    if (argc != 3) {

        printf("Usage: %s %s sourcecode input", argv[0], argv[1]);
    }
    else {
        char source[] = "This is an example.";
        int i;

        for (i = 0; i < sizeof(source); i++) {

            printf("%c", source[i]);
        }
    }

    getchar();

    return 0;
}

Это также НЕ работает:

char *source = "This is an example.";
int i;

for (i = 0; i < strlen(source); i++){

    printf("%c", source[i]);
}

Я получаю ошибку

Необработанное исключение в 0x5bf714cf (msvcr100d.dll) в Test.exe: 0xC0000005: нарушение доступа при чтении в позиции 0x00000054.

(в переводе с немецкого)

Так что не так с моим кодом?

Ответы [ 12 ]

53 голосов
/ 09 июля 2010

Вы хотите:

for (i = 0; i < strlen(source); i++){

sizeof дает вам размер указателя, а не строки. Однако это сработало бы, если бы вы объявили указатель как массив:

char source[] = "This is an example.";

но если вы передадите массив в функцию, он тоже затухнет до указателя. Для строк лучше всегда использовать strlen. И обратите внимание, что другие говорили об изменении printf для использования% c. А также, принимая во внимание комментарии mmyers относительно эффективности, было бы лучше перенести вызов strlen из цикла:

int len = strlen( source );
for (i = 0; i < len; i++){

или переписать цикл:

for (i = 0; source[i] != 0; i++){
39 голосов
/ 09 июля 2010

Одна распространенная идиома:

char* c = source;
while (*c) putchar(*c++);

Несколько замечаний:

  • В C строки оканчиваются нулем .Вы выполняете итерацию, пока прочитанный символ не является нулевым.
  • *c++ увеличивает c и возвращает разыменованное старое значение c.
  • printf("%s") печатает строку с нулевым символом в конце, а не символЭто является причиной нарушения вашего доступа.
3 голосов
/ 09 июля 2010

Вместо того, чтобы использовать strlen, как предложено выше, вы можете просто проверить наличие символа NULL:

#include <stdio.h>

int main(int argc, char *argv[])
{
    const char *const pszSource = "This is an example.";
    const char *pszChar = pszSource;

    while (pszChar != NULL && *pszChar != '\0')
    {
        printf("%s", *pszChar);
        ++pszChar;
    }

    getchar();

    return 0;
}
2 голосов
/ 09 июля 2010
  1. sizeof () включает завершающий нулевой символ. Вы должны использовать strlen () (но поместить вызов вне цикла и сохранить его в переменной), но это, вероятно, не то, что вызывает исключение.
  2. Вы должны использовать "% c", а не "% s" в printf - вы печатаете символ, а не строку.
2 голосов
/ 09 июля 2010

Это должно работать

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

 int main(int argc, char *argv[]){

    char *source = "This is an example.";
    int length = (int)strlen(source); //sizeof(source)=sizeof(char *) = 4 on a 32 bit implementation
    for (int i = 0; i < length; i++) 
    {

       printf("%c", source[i]);

    }


 }
2 голосов
/ 09 июля 2010

sizeof(source) возвращает количество байтов, необходимое указателю char*. Вы должны заменить его на strlen(source), который будет длиной строки, которую вы пытаетесь отобразить.

Кроме того, вам, вероятно, следует заменить printf("%s",source[i]) на printf("%c",source[i]), поскольку вы отображаете символ.

1 голос
/ 09 июля 2010
  • sizeof(source) возвращает вам размер char*, а не длину строки. Вы должны использовать strlen(source), и вы должны убрать это из цикла, иначе вы будете пересчитывать размер строки в каждом цикле.
  • При печати с модификатором формата %s, printf ищет char*, но вы фактически передаете char. Вы должны использовать модификатор %c.
0 голосов
/ 22 июня 2019

Последним индексом C-строки всегда является целочисленное значение 0, отсюда и фраза «строка с нулевым окончанием». Поскольку целое число 0 совпадает с логическим значением false в C, вы можете использовать его для создания простого предложения while для цикла for. Когда он достигает последнего индекса, он находит ноль и приравнивает его к ложному, заканчивая цикл for.

for(int i = 0; string[i]; i++) { printf("Char at position %d is %c\n", i, string[i]); }
0 голосов
/ 09 июля 2010

sizeof(source) возвращает размер указателя, так как источник объявлен как char *. Правильный способ использовать это strlen(source).

Далее:

printf("%s",source[i]); 

ожидает строку. Т.е.% s ожидает строку, но вы повторяете цикл для печати каждого символа. Следовательно, используйте% c.

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

0 голосов
/ 09 июля 2010

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

printf("%s", source + i);

сделает работу

Плюс, конечно, вы должны были иметь в виду strlen(source), а не sizeof(source).

...