singlepost

Строка с консоли (Си) << На главную или назад  

кто знает, как на Си взять строку нужного размера от пользователя, ну допустим, мне нужно, чтобы он ввел строку из 2 символов:
char str[2];
scanf("%s", &str);
в массив str занесется строка от пользователя, но если он введет больше 2 символо ведь они запишутся по адресу сразу же после этого массива, не напортят ли они чего?

69 ответов в теме “Строка с консоли (Си)”

  1. 30
    Ростислав Чутков ответил:

    В общем разобрались :)

  2. 29
    Dele Ted ответил:

    я подумал – все правильно, – так как при char a[n] место под массив выделяется во время компиляции – то &a == a, а если ты выделяешь char *a;
    a = malloc(n);
    то &a так и будет ссылаться на место(адресс) в программе выделенное при компиляции, а a уже будет ссылаться куда-то в память

    чо за ANSI/ISO- это оно и есть

  3. 28
    Dele Ted ответил:

    получается что при:
    char a[n];
    a==&a==&(a[0])

  4. 27
    Ростислав Чутков ответил:

    кстати. вот я че-то сам засомневался.

    2.13 Исходя из того, что ссылки на массив превращаются в указатели,
    скажите в чем разница для массива
    между array и &array?

    O:Согласно ANSI/ISO стандарту C, &array дает указатель типа
    "указатель-на-массив-Т", на весь массив (Cм. также вопрос 2.12).
    В языке C до выхода стандарта ANSI оператор & в &array игнорировался,
    порождая предупреждение компилятора.

    но я не понимаю чо за ANSI/ISO стандарт, я слышал только про C99…

  5. 26
    Dele Ted ответил:

    да, действительно, наверное я спутал с этим:
    #include <stdio.h>
    #include <stdlib.h>

    int main () {
    char *a;
    char i;
    a=malloc(sizeof(char)*100);
    for (i=0; i != 100; i++)
    a[i]=0;
    a[0]=1;
    a[1]=2;
    a[2]=3;
    a[3]=4;
    printf("%d, %d, %d, %d, %d\n",a,a[0],a[1],a[2],a[3]);
    printf("0x%x 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",a,&a,&(a[0]),&(a[1]),&(a[2]),&(a[3]));
    return 0;
    }

    ~/tests$ ./a.out
    134520840, 1, 2, 3, 4
    0×804a008 0xbfd4f874, 0×804a008, 0×804a009, 0×804a00a, 0×804a00b

  6. 25
    Ростислав Чутков ответил:

    When it comes to arrays, _pointer substitution does not occur in two places_:

    1. The address of an array, &array_name, is the address of the first element, not the address of some pointer constant.

    //www.sethi.org/classes/cet375/lab_notes/lab_05...

    хватит, короче, че-то придумывать =)

  7. 24
    Ростислав Чутков ответил:

    и ваще, не путайте людей..

  8. 23
    Ростислав Чутков ответил:

    вообще, ясно что можно производить адресную арифметику с указателем, но вопрос был в &имя_массива и просто имя_массива, это другое)

  9. 22
    Dele Ted ответил:

    имя_массива == указатель на 0-й элемент массива
    &имя_массива == указатель на указатель 0-го элемента массива

  10. 21
    Dele Ted ответил:

    &(имя_массива[0]) == указатель на 0-й элемент массива
    &(имя_массива[1]) == указатель на 1-й элемент массива
    &(имя_массива[n]) == указатель на n-й элемент массива

  11. 20
    Dele Ted ответил:

    на сколько я знаю смещённый указатель это типа следующего:
    char *a;
    * c;
    a=malloc(100);
    c=a+99;
    while (a != c) {
    printf("%d ",a);
    a++; // <— смещение указателя
    }
    указатель со смещением:
    char *a;
    char c;
    c=0;
    a=malloc(100);
    while (c != 99) {
    printf("%d ",a[c]); // <—- указатель со смещением
    c++;
    }
    или:
    char *a;
    char c;
    c=0;
    a=malloc(100);
    while (c != 99) {
    printf("%d ",a+c); // <—- указатель со смещением
    c++;
    }

    сам указатель в последних двух примерах и вашем – не меняется

  12. 19
    Евгений Гаврин ответил:

    size_tLength0 = 40;
    dataOut0=(char*)malloc(sizeof(char)*dataOutLength0+FrmHeader);

    SetID( dataOut0+FrmHeader , 0 );
    Store( dataOut0, Length0, NULL);

  13. 18
    Dele Ted ответил:

    а где это ты в программе найдёшь сдвинутый указатель, кто его сдвинул и для чего? o_O

  14. 17
    Евгений Гаврин ответил:

    Тебя практический пример интересует? могу кусок кода кинуть

  15. 16
    Ростислав Чутков ответил:

    вообще мне тоже интересно)

  16. 15
    Евгений Гаврин ответил:

    Просто если брать str – то да он будет указывать на начало массива. А если мы имеем указатель – мы хз что там, мб там сдвинутый указатель, или указатель на тридесятый эл массива.

  17. 14
    Dele Ted ответил:

    дауж тут главное не запутаться, просто нужно помнить, что функции не выгодно передавать массив, а выгодно передавать указатель на массив(иначе что былобы со стеком, передай бы пару тыщь long long int-ов :) )

    всё просто:
    unsigned long long int a[1000];

    в a – сохранится указатель(адресс в памяти) на 0-й элемент массива
    long long int – виличина блоков по 64 бита

    определение функции scanf: int scanf (const char *template, …)
    - все параметры – адреса на нужные буферы а так как a уже сам по себе указатель то перед ним не нужно ставить & потомучто иначе получится указатель на буфер с указателем

  18. 13
    Ростислав Чутков ответил:

    Александра Dream Письминская, вот, так лучше) хотя ежели честно, начинающих больше пугает неоднородность синтаксиса, почему нужно писать /*int i*/ scanf("%i",&i) но /*char s[80]*/ scanf("%s",s)
    хотя согласен, что эта проблема встанет ребром для char* str = new char[80]();
    но на то все таки C и есть чтоб напрячь моск)

  19. 12
    Ростислав Чутков ответил:

    упс, не new а malloc разумеется.

  20. 11
    Александра Письминская ответил:

    2Ростислав Чутков
    Да, ты прав. Просто &str- масло масляное- адрес от указателя… Это может запутать начинающих.
    Про двойку и речь не шла, думаю, что это было понятно и из предыдущих сообщений.
    2Евгений KpoHyc Гаврин
    После объявления массива str все же указывает на начало.

  21. 10
    Dele Ted ответил:

    >а не факт, что str указывает на начало массива
    str – указатель на первый элемент если str определён как на пример char str[n];

    str == &(str[0])

  22. 9
    Евгений Гаврин ответил:

    а не факт, что strуказывает на начало массива

  23. 8
    Ростислав Чутков ответил:

    Александра Dream Письминская, в данном случае наличие & не имеет значения. функции нужен указатель, &str – это указатель на начало массива, str – это неявный указатель на начало массива. вопрос вкуса, но CERT говорит, что указатели лучше использовать явные.

    а вот scanf("%s", str); – неверно, выше я уже писал что нужен "%2s" (и автор вопроса, кстати, именно про это и спрашивал)

    Вот такое когда-нибудь получали: Run-Time Check Failure #2 – Stack around the variable 'name' was corrupted.?

  24. 7
    Александра Письминская ответил:

    >Алексей [°] Alex_Hell [°] Поляков

    char str[3];
    scanf("%s", str);

    Без &

  25. 6
    Алексей Поляков ответил:

    Спасибо)

  26. 5
    Ростислав Чутков ответил:

    ну да, fgets оно и в африге фгетс. но у автора был конкретный вопрос =)

  27. 4
    Dele Ted ответил:

    а ничё, что для получения нужного кол-ва символов есть специальные функции? незнаю как там в MS, думаю что почти также, но рекомендую покурить это //www.gnu.org/software/libc/manual/html_mono/li...

  28. 3
    Евгений Гаврин ответил:

    scanf("%с%с",&str[1], &str[2]);

  29. 2
    Ростислав Чутков ответил:

    Напортят.

    Security NoteWhen reading a string with scanf, always specify a width for the %s format (for example, "32%s" instead of "%s"); otherwise, improperly formatted input can easily cause a buffer overrun. Alternately, consider using fgets.

    Вообще, MSDN очень хорошее место, чтобы узнавать ответы на такие вопросы.

    //msdn.microsoft.com/en-us/library/9y6s16×1(VS.71).aspx

  30. 1
    Ростислав Чутков ответил:

    тебе нужно %2s
    и строку ессно char str[3]; // 2chars + null

Клуб программистов работает уже ой-ой-ой сколько, а если поточнее, то с 2007 года.