Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
0 / 0 / 0
Регистрация: 28.04.2009
Сообщений: 118

Цикл не дает записать данные в переменную

25.05.2009, 02:33. Показов 2153. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C
1
2
3
4
5
6
7
8
9
10
while (1){
                memset(mess, 0, sizeof(mess));
                 printf("Vvedite comandu\n");
                 gets(mess);
                 printf("mess:%s", mess);
                 memset(&str, 0, sizeof(str));
                 sprintf(str, "%s %s", mess, id_end);
                 printf("str:%s", str);
                 send(sd, str, strlen(str)+1, 0);
         }
Выводит:
Vvedite comandu
mess:str: end
Vvedite comandu
//здесь уже можно вводить

Короче получается первый раз цикл проходит и не дает записать в переменную mess.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
25.05.2009, 02:33
Ответы с готовыми решениями:

Как записать данные в переменную, не имея указатель на неё?
Столкнулся с такой проблемой. Сейчас изучаю c по книге K&R. Нашёл там пример применения библиотеки stdarg в создании упрощённой функции для...

Как записать в переменную данные из структуры, а не адрес на структуру?
Подскажите пожалуйста, есть ли способ записать в переменную *char именно сами данные, а не адрес на структуру? Или где я ошибаюсь? ...

Процедуры: записать в переменную А минимальное из значений А и В, а в переменную В - максимальное
Описать процедуру minmax (a,b) что записывает в переменную А минимальное из значений А и В, а в переменную В - максимальное из этих...

17
43 / 39 / 12
Регистрация: 05.01.2009
Сообщений: 394
25.05.2009, 03:07
а что было до цикла?
попробуй очищать поток ввода
fflush (stdin);
1
0 / 0 / 0
Регистрация: 28.04.2009
Сообщений: 118
25.05.2009, 08:50  [ТС]
Попробововал очищать, но все равно не то.
До цикла с потоком ввода были операции:
C
1
2
3
4
                printf("Enter login:\n");
                scanf("%s", login);
                printf("Enter pass:\n");
                scanf("%s", pass);
Добавлено через 3 минуты 55 секунд
Вот что показывает gdb перед циклом
print stdin
$1 = (struct _IO_FILE *) 0xb7ed3420

Добавлено через 1 минуту 28 секунд
Содержимое mess перед циклом
print mess
$3 = "\025\000��\025\000��\025\000�'\000\000� T\000\000\006\000\000\000\000\020\000\00 0\002\000\000\000|�\025\000|�\025\000|�\ 025\000�\000\000\000�\000\000\000\006\00 0\000\000\004\000\000\000\004\000\000\00 0t\001\000\000t\001\000\000t\001\000\000 \000\000\000 \000\000\000\004\000\000\000\004\000\000 \000\a\000\000\000��\025\000��\025\000�� \025\000\b\000\000\000@\000\000\000\004\ 000\000\000\004\000\000\000P\vط\020ii\r� m࿸,��\036dط\230���\004\000\000\000�\212� �p\215��\002\000��h\215��\006dط�\212���o ��\024\213��\001\000\000\000Tn࿭0����\025 \000��"...

Добавлено через 7 минут 10 секунд
Переменная mess после очищения в начале цикла
print mess
$6 = '\0' <repeats 1023 times>

Добавлено через 54 секунды
Правда надо сказать, что второй проход по циклу выполняется нормально и он дает ввод команды

Добавлено через 5 часов 13 минут 38 секунд
UP
0
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
25.05.2009, 09:17
очищать поток ввода нельзя, это даёт undefined behavior (непредсказуемое поведение)
цикл может проскакивать из-за того что в потоке ввода что-то есть, лучше это просто прочитать, вставив перед циклом scanf("\t"); если там перевод строки, он уйдёт в этот scanf
1
0 / 0 / 0
Регистрация: 28.04.2009
Сообщений: 118
25.05.2009, 10:13  [ТС]
Перед циклом gdb показывает такую картину:
(gdb) print stdin
$1 = -1207946208

Добавлено через 6 минут 24 секунды
Не помогло использование scanf... Все равно проскакивает первый цикл

Добавлено через 25 минут 52 секунды
Может кто-нибудь подскажет как должен выглядеть stdin если смотреть в gdb??
0
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
25.05.2009, 10:25
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
while (1) {
        memset(mess, 0, sizeof mess);
        printf("Vvedite comandu\n");
        
        gets(mess);
        /* fgets(mess, sizeof mess, stdin); */
        
        printf("mess: %s\n", mess);
        /* printf("mess: %s", mess); */
        
        memset(str, 0, sizeof str);
        sprintf(str, "%s %s", mess, id_end);
        printf("str: %s", str);
        /* send(sd, str, strlen(str)+1, 0); */
    }
лучше, конечно, fgets юзать, там и глюка этого нет, и длину контролирует

Добавлено через 1 минуту 25 секунд
обратная к gets функция puts, то есть gets обрезает перевод, а puts приписывает перевод (даже если там уже есть)
поэтому, когда gets читает, как бы и не поймёшь, а был там перевод или может не было (типа писать его или не писать)
1
0 / 0 / 0
Регистрация: 28.04.2009
Сообщений: 118
25.05.2009, 12:13  [ТС]
Да я юзал gets, там было что-то типо этого, но он добавляет \n в конце, а мне он там не нужен. И собственно тогда вопрос - как удалить последний символ \n из строки??

Добавлено через 30 секунд
*fgets

Добавлено через 10 минут 12 секунд
Вообщем и с fgets не работает. Проскакивает. Причем перед циклом делаю:
C
1
scanf("\t");
И без него тоже проскакивает. Уже не знаю что делать (((

Добавлено через 50 минут 12 секунд
UP

Добавлено через 45 минут 54 секунды
Никто видимо не знает что делать...((
0
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
26.05.2009, 04:28
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <string.h>
 
main()
{
    char mess[100], str[100], id_end[100] = "end";
    
    while (1) {
        memset(mess, 0, sizeof mess);
        printf("Vvedite comandu\n");
        
        gets(mess);
        /* fgets(mess, sizeof mess, stdin); */
        
        printf("mess: %s\n", mess);
        /* printf("mess: %s", mess); */
        
        memset(str, 0, sizeof str);
        sprintf(str, "%s %s\n", mess, id_end);
        printf("str: %s", str);
        /* send(sd, str, strlen(str)+1, 0); */
    }
    return 0;
}
вывод
Code
1
2
3
4
5
6
[guest@station src]$ ./test
Vvedite comandu
one
mess: one
str: one end
Vvedite comandu
1
0 / 0 / 0
Регистрация: 28.04.2009
Сообщений: 118
26.05.2009, 08:18  [ТС]
Ну у меня по ходу где-то до цикла с буфером не в порядке... И не могу отладчиком отследить состояние

Добавлено через 57 минут 3 секунды
Собственно вот функция, которая вызывается ДО цикла:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//Authorization
 int auth(char* port, char *login, char *pass){
 
         int sd_log;
         struct sockaddr_in addr;
         char id[3] = "lg";
         char id_end[5] = "end\n";
         char str[BUFFER];
         char buf_out[300];
         char buf_in[300];
 
         sd_log = socket(AF_INET, SOCK_STREAM, 0);
              if (sd_log < 0){
                 perror("connect");
                 exit(3);
             }
 
         addr.sin_family = AF_INET;
         addr.sin_port = htons(atoi(port));
         addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
         if (connect(sd_log, (struct sockaddr *)&addr, sizeof(addr)) < 0){
                 perror("connect");
                 exit(4);
         }
 
        while (strcmp(buf_in, "OK")){
 
                 memset(login, 0, sizeof(login));
                 memset(pass, 0, sizeof(pass));
                 memset(buf_out, 0, sizeof(buf_out));
                 memset(buf_in, 0, sizeof(buf_in));
 
                 printf("Enter login:\n");
                 scanf("%s", login);
                 printf("Enter pass:\n");
                 scanf("%s", pass);
 
                 sprintf(buf_out, "%s %s %s %s", id, login, pass, id_end);
                 send(sd_log, buf_out, strlen(buf_out)+1, 0);
                 recv(sd_log, buf_in, sizeof(buf_in), 0);
         //      printf("%s\n", buf_in);
 
                 if (strcmp(buf_in, "OK") == 0){
                         printf("Авторизация прошла успешно\n");
                         close(sd_log);
                         return 0;
                 }
                 else {
                         sleep(3);
                         printf("Not correct login/pasword. Please retrying...\n")
                 }
         }
return 0;
}
Добавлено через 1 минуту 8 секунд
Без нее цикл не проскакивает...
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
26.05.2009, 10:34
Цитата Сообщение от toxxin Посмотреть сообщение
C
1
2
3
4
5
6
7
8
9
10
while (1){
                memset(mess, 0, sizeof(mess));
                 printf("Vvedite comandu\n");
                 gets(mess);
                 printf("mess:%s", mess);
                 memset(&str, 0, sizeof(str));
                 sprintf(str, "%s %s", mess, id_end);
                 printf("str:%s", str);
                 send(sd, str, strlen(str)+1, 0);
         }
Выводит:
Vvedite comandu
mess:str: end
Vvedite comandu
//здесь уже можно вводить

Короче получается первый раз цикл проходит и не дает записать в переменную mess.
У тебя печать немого не соотвествует коду. Ещё раз покажи аккруатно, что именно ты ввдил. Или ты имеешь в виду, что ты ничегоне вводил, а gets проскочило, как будто ты что-то ввёл? И покажи на всякий случай типы mess, str, id_end

Добавлено через 2 минуты 23 секунды
Цитата Сообщение от toxxin Посмотреть сообщение
Без нее цикл не проскакивает...
Теоретически пробелма в том, что у тебя используется scanf. Т.е. ввыдишь строку и жмёшь энтер. В scnaf'е у тебя заполняется строка, но энтер не читается и залипает в буффере ввода. А при следующем запуске gets он из буффера достаётся и получается так, что как будто ты в этом месте ввёл энтер

Советую везде для ввода использовать fgets, при этом перед запуском fgets всегда делать fflush (stdin)
1
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
26.05.2009, 10:45
Цитата Сообщение от Evg
перед запуском fgets всегда делать fflush (stdin)
я выше писал насчёт stdin

Без нее цикл не проскакивает...
C
1
scanf("%s", login);
закомментируй строки со scanf а значения вручную занеси через strcpy и посмотри будет ли проскакивать
(ещё scanf не ограничен по длине ввода, там можно ввести поле scanf("%100s", login) ну и формировать его перед сканфом всю форматную строку типа sprintf(fmtline, "%%100s") )
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
26.05.2009, 11:07
Цитата Сообщение от accept Посмотреть сообщение
очищать поток ввода нельзя, это даёт undefined behavior (непредсказуемое поведение)
Действительно, fflush по документации правильно запсукать только на потоки ВЫвода, на потоки ВВода он не влияет.

Тогда нужно аккруатно написать отдельную процедуру для ввода строки. В первоначальном варианте она будет состоять из одного fgets и работать мы будем в предположении, что пользователь вводит строки, заканчивающиеся энтером и заведомо умещающиеся в буффер. А в будущем, если понадобится, надо будет отдельно разбираться с тем, как работать с длинным вводом, чтобы лишние данные не залипали в буффере
1
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
26.05.2009, 11:12
Цитата Сообщение от Evg
на потоки ВВода он не влияет.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
7.19.5.2  The fflush function
 
       Synopsis
 
       [#1]
 
               #include <stdio.h>
               int fflush(FILE *stream);
 
       Description
 
       [#2] If stream points to  an  output  stream  or  an  update
       stream in which the most recent operation was not input, the
       fflush function causes any unwritten data for that stream to
       be  delivered  to  the host environment to be written to the
       file; otherwise, [B]the behavior is undefined[/B].
 
       [#3] If stream  is  a  null  pointer,  the  fflush  function
       performs  this  flushing action on all streams for which the
       behavior is defined above.
 
       Returns
 
       [#4] The fflush function sets the error  indicator  for  the
       stream and returns EOF if a write error occurs, otherwise it
       returns zero.
это со стандарта С99
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
26.05.2009, 11:19
С учётом того, что у toxxin'а linux и glibc, то корректнее было бы читать именно man от glibc.

Code
1
2
3
4
       The  function  fflush()  forces  a  [B]write[/B] of all user-space buffered data for the given [B]output[/B] or update stream via the
       stream's underlying write function.  The open status of the stream is unaffected.
 
       If the stream argument is NULL, fflush() flushes all open [B]output[/B] streams.
Формулировка, как обычно расплывчатая, но я её понимаю так, что fflush именно сбрасывает буффера ВЫвода. Итог в любом случае не меняется - fflush нам в данном случае скорее всего не поможет. "Скорее всего" - потому как для любого gnu'того продукта в порядке вещей делать то, чего в документации нет
1
0 / 0 / 0
Регистрация: 28.04.2009
Сообщений: 118
26.05.2009, 13:06  [ТС]
Спасибо большое

Добавлено через 3 минуты 39 секунд
Тогда нужно аккруатно написать отдельную процедуру для ввода строки.
Вот это мне всегда мозг выносит.)) 2009 год. На си кодят уже туеву времени и нет самых обычных и нормальных функций для работ со строками!!! Написано дофига крутых функций для работы со сложнейшими вещами, ядро линукса тут недавно перевалило за какой-то там миллионный(миллиардный) рубеж строк, а считать адекватно строчку просто так невозможно. Ну как же так...
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
26.05.2009, 14:06
Язык Си - оннизкоуровневый. Библиотека тебе обеспечивает только набор строительных кирпичей, из которых там строишь то, что тебе нужно и так, как тебе нужно. Тебе выдали функцию fgets - пользуйся на здоровье. Только следи за заполняемостью буффера и если он заполнен под завязку, значит тебе нужно ещё раз дёрнуть функцию, чтобы прочитать буффер до конца

На Си++ это всё накрыто стандартными классами и тебе достаточно написать "cout << Str;". Правда ха этой строкой кроется работы, время исполнения которой в разы и десятки раз превышает время работы аналога на Си. Т.е. всё сразу не бывает - либо добно, либо быстро. Причём на Си ты этими кирпичами вертишь как хочешь с целью выжимания максимальной производительности из кода. На Си++ в большинстве случаев ты этого либо лишён, либоделается всё через три жо$ы

Ну вот примерно так

Если хочешь использовать какие-то обощённые функции ввода-вывода, чтобы самому их не писать - пожалуйста. Всё это реализовано в библиотеках типа termcap/ncurses. По умолчанию они у тебя стоЯт на машине, только надо разобраться как с ними работать
1
0 / 0 / 0
Регистрация: 28.04.2009
Сообщений: 118
26.05.2009, 14:48  [ТС]
Спасибо. Это скорее был риторический крик)) Так-то я в принципе понимаю в каких ситуациях лучше использовать какой язык...
0
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
27.05.2009, 04:33
Цитата Сообщение от Evg
С учётом того, что у toxxin'а linux и glibc, то корректнее было бы читать именно man от glibc.
да не, корректнее всегда читать стандарт, undefined behavior значит, что программа вообще может вывалиться, если применить
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
27.05.2009, 04:33
Помогаю со студенческими работами здесь

Организовать цикл по DataTable и записать ID в переменную
Вообщем есть запрос(ИНСЕРТ...), в него нужно вставить значение полученное с другой таблицы. Например: SELECT MAX(id) FROM Table1. ...

как записать переменную и что бы цикл выполнялся
Всем привет! Я зеленый новичок и нуждаюсь в совете. Есть код: var counter = ; for (var i = 1;i &lt;= 24;i++) { ...

(WinCC) записать данные в глобальную переменную
Есть Simatic 7 Step программа. В ней есть Global Script, где я пишу свои функции. Но жизненный цикл переменных не дает ее запомнить к...

Данные из ячейки записать в переменную
Здравствуйте! у меня есть dataset.Tables т е в dataset есть datatable. Как мне записать в переменную значение из, например, первого столбца...

Как записать в переменную данные из QDateTimeEdit?
Помогите, пожалуйста,есть QDateTimeEdit, пользователь ввёл в него время и дату, и мне нужно работать с переменной, содержащей эти данные. Я...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru