One specific variable reference is being skipped

Refresh

5 days ago

Views

63 time

0

It seems like the %s in the final printf is entirely being skipped.

This is the entire code:

#include <stdio.h>

int main(void){
    char address[100];
    char city[100];
    char state[2];
    char zip[15];

    printf("Enter street address: ");
    scanf(" %[^\n]",&address);

    printf("Enter city: ");
    scanf(" %[^\n]",&city);

    printf("Enter state: ");
    scanf(" %s",&state);

    printf("Enter ZIP Code: ");
    scanf(" %s",&zip);

    printf("%s\n%s, %s %s",address,city,state,zip);

    return 0;
}

When this address is entered:

1 Main Street
New York City, NY 12345

The program prints:

1 Main Street
, NY 12345

I can't figure out the cause of this issue.
Any help would be greatly appreciated because I'm out of ideas.

3 answers

0

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

  1. Попытка прочитать состояние "NY"в виде строки в char state[2];. Чтобы допустимая строка в C, символы должны заканчиваться NUL оконечного характером. Значение для хранения состояния аббревиатуры 2-символьной, вам нужны 3-символы хранения (минимум). Например {'N', 'Y', '\0'}. (Master @JonathanLeffler выводится как непосредственное следствие кратковременного хранения для stateможет привести к '\0'персонажу быть сохранено в качестве первого символа в cityрезультате чего cityбудет пустой строка);
  2. При чтении строки с scanfвами должны предоставить указатель на достаточное хранилище для строки , которую вы читаете. Поскольку address, city, state, zipявляются символьные массивы, на доступ, они преобразуются в указатель на первый символ (см С11 стандарт - 6.3.2.1 Другие операнды - Lvalues, массивы и функции обозначения (p3) ) Таким образом , каждый из них уже указатель при использовании в качестве аргумент для scanfи нет '&'(адрес) оператора необходимо перед ними в списке аргументов.

Дополнительные замечания, избегать использования магических чисел в коде , если это абсолютно необходимо. 100, 2, 15являются магическими-числами ниже.

    char address[100];
    char city[100];
    char state[2];
    char zip[15];

Если вам нужна константа для числа символов в address, city, state, zip, по #defineодному для каждой или использовать глобальный , enumчтобы сделать то же самое, например ,

enum { STSZ = 3, ZIPSZ = 15, CIADDR = 100 };    /* constants */

( Обратите внимание city , и addressоба 100, поэтому одна CIADDRконстанта будет делать)

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

Положив эти части вместе, и думать вперед , что вы просто можете найти себе дело с более чем 1 адресом в коде, следующий пример , который может считывать city, state zipзначения в одной строке текста и значения сохраняются в структуре. (что позволяет объявить массив структуры, или указатель и выделить в случае необходимости при работе с более чем один адрес позже)

#include <stdio.h>

enum { STSZ = 3, ZIPSZ = 15, CIADDR = 100 };    /* constants */

typedef struct {            /* simple struct presuming in the future */
    char address[CIADDR],   /* you may have more than 1 address */
        city[CIADDR],
        state[STSZ],        /* STSZ must be 3 to read a string of 2-char */
        zip[ZIPSZ];
} loc_t;

int main (void) {

    loc_t location1 = { .address = "" };    /* declare/initialize struct */

    printf ("enter street address: ");      /* prompt/read/validate address */
    if (scanf (" %99[^\n]", location1.address) != 1) {
        fputs ("sscanf() error: invalid address.\n", stderr);
        return 1;
    }

    printf ("enter city: ");                /* prompt/read/validate city */
    if (scanf (" %99[^,],", location1.city) != 1) {
        fputs ("sscanf() error: invalid city.\n", stderr);
        return 1;
    }

    printf ("enter state: ");               /* prompt/read/validate state */
    if (scanf (" %2s", location1.state) != 1) {
        fputs ("sscanf() error: invalid state.\n", stderr);
        return 1;
    }

    printf ("enter zip: ");                 /* prompt/read/validate zip */
    if (scanf (" %14s,", location1.zip) != 1) {
        fputs ("sscanf() error: invalid zip.\n", stderr);
        return 1;
    }

    /* output results preceeded by 2-newlines */
    printf ("\n\n%s\n%s, %s %s\n", location1.address, location1.city,
            location1.state, location1.zip);
}

( Примечание: номера для поля шириной модификаторов включены в каждом scanfвызове , чтобы защитить свои границы массива дополнительно несколько. '\n'До вывода компенсирует неиспользованные подсказки , когда city, state zipэто все введенных на "city: "строке)

Пример использования / вывода

Ввод "New York City, NY 12345"в одну строку в "enter city: "строке:

$ ./bin/readaddr
enter street address: 1 Main Street
enter city: New York City, NY 12345
enter state: enter zip:

1 Main Street
New York City, NY 12345

Посмотрите снова и дайте мне знать, если у вас есть дополнительные вопросы.

0
#include <stdio.h>

int main(void){
    char address[100];
    char city[100];
    char state[2];
    char zip[15];

    printf("Enter street address: ");
    scanf(" %[^\n]",&address);

    printf("Enter city: ");
    scanf(" %[^\n]",&city);

    printf("Enter state: ");
    scanf(" %s",&state);

    printf("Enter ZIP Code: ");
    scanf(" %s",&zip);

    printf("\nONE: %s\n",address);
    printf("TWO: %s\n",city);
    printf("THREE: %s\n",state);
    printf("FOUR: %s\n",zip);

    return 0;
}

Скопируйте вставьте в https://www.codechef.com/ide , и вы увидите следующий вывод:

Enter street address: Enter city: Enter state: Enter ZIP Code: 
ONE: 1 Main Street
TWO: New York City, NY 12345
THREE: 
FOUR: @

Вы храните все в городе, вместо того чтобы останавливаться на запятой. Что вы думаете, что ваш зсапЕ для города делает?

0

Код Следование хорошо работать на моей рабочей станции.

#include <stdio.h>
int main(void){
    char address[100];
    char city[100];
    char state[2];
    char zip[15];
    printf("Enter street address: ");
    scanf(" %[^\n]",address);
    printf("Enter city: ");
    scanf(" %[^\n]",city);
    printf("Enter state: ");
    scanf(" %s",state);
    printf("Enter ZIP Code: ");
    scanf(" %s",zip);
    printf("%s\n%s, %s %s",address,city,state,zip);
    return 0;
}