Как отмечено в комментариях и других ответах, у вас есть ряд проблем.Первые два, которые немедленно вызывают неопределенное поведение :
- Попытка прочитать состояние
"NY"
в виде строки в char state[2];
.Чтобы быть допустимой строкой в C, символы должны заканчиваться символом nul-terminating .Это означает, что для хранения двухсимвольной аббревиатуры необходимо 3-х символьное хранилище (минимум).Например, {'N', 'Y', '\0'}
.(Мастер @ JonathanLeffler сделал вывод, как непосредственное последствие короткого хранения для state
может привести к тому, что символ '\0'
будет сохранен как первый символ в city
, в результате чего city
станет пустым-string); - При чтении строк с помощью
scanf
вы должны предоставить указатель на достаточный объем памяти для строки, которую вы читаете.Поскольку address, city, state, zip
являются символьными массивами, при обращении они преобразуются в указатель на первый символ (см .: Стандарт C11 - 6.3.2.1 Другие операнды - L-значения, массивы и обозначения функций (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 */
( note city
и address
оба 100
, поэтому подойдет одна CIADDR
константа)
Когда номер абсолютно необходим в вашем коде?При предоставлении модификатора field-width для защиты границ массива при чтении с помощью семейства функций scanf
.Кроме того, при использовании семейства scanf
вы должны каждый раз проверять возврат .В противном случае может произойти сбой , соответствующий или , (или пользователь может сгенерировать руководство EOF
для отмены ввода), и вы будете вслепую продвигаться вперед, используя переменную, которая не была заполнена и, вероятно,оставлено неопределенным, вызывая неопределенное поведение .
Собирая эти кусочки и думая, что вы можете столкнуться с более чем одним адресом в вашем коде, ниже приведен пример, который может прочитатьcity, state zip
значения в одной строке текста и значения хранятся в структуре.(который позволяет объявлять массив struct или указатель и выделять его при необходимости при работе с более чем одним адресом позже)
#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);
}
( note: числа для *Модификаторы 1073 * field-width включены в каждый вызов 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
Просмотрите все идайте мне знать, если у вас есть дополнительные вопросы.