Как было отмечено в комментариях , и в других ответах, у вас есть целый ряд проблем. Первые два , которые сразу же вызвать неопределенное поведение , являются:
- Попытка прочитать состояние
"NY"
в виде строки в char state[2];
. Чтобы допустимая строка в C, символы должны заканчиваться NUL оконечного характером. Значение для хранения состояния аббревиатуры 2-символьной, вам нужны 3-символы хранения (минимум). Например {'N', 'Y', '\0'}
. (Master @JonathanLeffler выводится как непосредственное следствие кратковременного хранения для state
может привести к '\0'
персонажу быть сохранено в качестве первого символа в city
результате чего city
будет пустой строка);
- При чтении строки с
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
Посмотрите снова и дайте мне знать, если у вас есть дополнительные вопросы.