Почему я не могу использовать коллокации в strcmp ()? - PullRequest
1 голос
/ 23 января 2020

Следующий код не работает:

char text[10];
    scanf(" %s", &text);

    if (strcmp(text, "some text") == 0)
        puts("some text");

Но когда я изменяю 'если часть' таким образом, то все в порядке:

if (strcmp(text, "sometext") == 0)

почему это работает так и как это исправить?

Ответы [ 4 ]

3 голосов
/ 23 января 2020

Проблема не в вашем strcmp вызове, а скорее в вашем scanf вызове! Когда вы введете some text в качестве ввода, scanf прекратит чтение с первого пробела, поэтому ваша строка text будет иметь значение "some" - и, таким образом, вызов strcmp вернет (правильно) ненулевое значение , поскольку это , а не то же самое, что и "некоторый текст".

Для получения дополнительной информации об этой функции scanf, пробелах и формате %s см. эту топи c : Как разрешить ввод пробелов с помощью scanf?

2 голосов
/ 23 января 2020

вызовите fgets для чтения пробела и сравнения строк с помощью strncmp:

fgets (text, 100, stdin);
puts(text);
if (strncmp(text, "some text",9) == 0)
    puts("some text");
0 голосов
/ 23 января 2020

Off-topi c, но слишком долго для комментария.

Ваша строка scanf на самом деле неверна (не относится к пробелам), и вам просто повезло, что она работает здесь , Вам нужно удалить амперсанд & перед text. То, что у вас есть, передает адрес text на scanf, который фактически является указателем на char[10]. Для scanf(" %s", text);, text «распадается» на указатель на его первый элемент (char*), который вы действительно хотите. Здесь, так уж получилось, что адрес массива (&text) совпадает с адресом первого элемента в массиве (&(text[0]) или *(text + 0)), так как они оба в автомате c хранение в том же месте. Например, если бы у вас было что-то вроде

char* text = malloc(10);
scanf(" %s", &text);

, вы бы вызвали неопределенное поведение, перезаписав память, начиная с адреса указателя на вашу malloc память. Здесь адрес текста - это адрес указателя в автоматическом c хранилище, тогда как память, на которую он фактически указывает, находится где-то еще. Это можно увидеть в следующей программе:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char text[10];
    char* text2 = malloc(10);

    printf("address of text = %p\n", (void*)(&text));   // same address as below
    printf("address of text[0] = %p\n", (void*)(&(text[0])));  // same address as above
    printf("address of text2 = %p\n", (void*)&text2);   // different than below
    printf("address of text2[0] = %p\n", (void*)(&(text2[0])));  // different than above

    return 0;
}

&text == &(text[0]), показывающие, что адрес массива и адрес первого элемента массива эквивалентны, однако &text2 != &(text2[0]), показывающий адрес указатель не равен адресу первого элемента памяти, который вы malloc изм.

Иллюстрированный здесь: https://godbolt.org/z/N2TKvK

0 голосов
/ 23 января 2020

Мой ответ будет о том, как разобраться в таких проблемах, не задавая вопросов на форуме. Я бы потратил 2-3 минуты, чтобы посмотреть, что там происходит:

int main()
{
    char text[10];
    int result;
    result = scanf(" %s", &text);

    printf("scanf result: %d, scanned text: \"%s\"\n", result, text);

    if (strcmp(text, "some text") == 0)
        puts("some text");

}

Отладка - ie найти источник проблем так же важно, как знание программирования. Если вы добавите эту единственную строку самостоятельно, вы бы сами решили эту проблему в кратчайшие сроки.

Попробуйте сами: https://godbolt.org/z/Tmy7PA

...