Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
0 / 0 / 0
Регистрация: 02.02.2018
Сообщений: 2
1

Вывод printf

02.02.2018, 21:28. Показов 1279. Ответов 15

Привет всем, я тут начал изучать язык си и вот столкнулся с проблемой. Программа преобразует массив [a, b, c, d] в [b, c, d, a].
В принципе работает но выводит лишние символы "MMMMM"
вот код:
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
#include <stdio.h>
#include <locale.h>
 
 
int main(void)
{
    char *locale = setlocale(LC_ALL, "");
 
    int i, j, t;
    char arr[] = { 'a', 'b', 'c', 'd' };
 
    printf("Исходный порядок букв: ");
    for (i = 0; i < arr[i]; i++)
        printf("%c", arr[i]);
 
    printf("\n");
 
    printf("Изменненый порядок букв: ");
    for (j = 0; j < arr[j]; j++)
    {
        t = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = t;
        printf("%c", arr[j]);
 
    }
    
    
    printf("\n");
 
    return 0;
}


а вот вывод:
Исходный порядок букв: abcd
Изменненый порядок букв: bcdММММММММa


не могу понять откуда символы MMMMM берутся
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.02.2018, 21:28
Ответы с готовыми решениями:

Вывод символов printf
Не могу понять, почему когда я значения переменных заключаю в двойные кавычки, то у меня выводится...

Неверный вывод printf
Доброго времени суток. Код printf(&quot;%s %s\n&quot;,byte_to_binary(i), byte_to_binary(sbox1(i))); где ...

Вывод кириллицы через printf
Как вывести кириллицу, то есть: printf(&quot;Абра кадабра&quot;); и получать нормальный текст, как это...

Вывод одномерного массива через printf
Пожалуйста, помогите правильно написать вывод, по возможности в printf и % cout « &quot;mas X::&quot;;...

15
1463 / 1171 / 551
Регистрация: 08.01.2012
Сообщений: 4,514
02.02.2018, 21:44 2
Цитата Сообщение от TUfeed Посмотреть сообщение
for (j = 0; j < arr[j]; j++)
здорово
0
Evg
Эксперт CАвтор FAQ
21177 / 8192 / 630
Регистрация: 30.03.2009
Сообщений: 22,496
Записей в блоге: 30
02.02.2018, 21:44 3
В условиях цикла вместо "i < arr[i]" должно быть "i < 4". Ну или "i < ((sizeof(arr)/sizeof(arr[0]))" если уж совсем по-пацански

После этого у тебя всё равно останется ошибка в программе, но постарайся найти её сам
1
0 / 0 / 0
Регистрация: 02.02.2018
Сообщений: 2
02.02.2018, 22:34  [ТС] 4
C
1
2
3
4
5
6
7
8
for (j = 0; j < (sizeof(arr)-1); j++)
    {
        t = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = t;
        printf("%c", arr[j]);
 
    }
теперь теряется где-то последний символ.
всего получается 3 шага в цикле
1. a,b,c,d => b,a,c,d
2. b,a,c,d => b,c,a,d
3. b,c,a,d => b,c,d,a
но почему теряется последний символ?
если
C
1
for (j = 0; j < (sizeof(arr)); j++)
то вылетает ошибка "стек вокруг переменной " arr " был поврежден"
вышел за пределы массива? мне кажется что нет.
а если
C
1
for (j = 0; j < (sizeof(arr)-1); j++)
то последний символ просто теряется.

Добавлено через 12 минут
все таки выход за пределы массива
0
1480 / 886 / 573
Регистрация: 25.04.2016
Сообщений: 2,459
02.02.2018, 22:57 5
Лучший ответ Сообщение было отмечено TUfeed как решение

Решение

char *locale = setlocale(LC_ALL, "");
замените на
setlocale(LC_ALL, "");

вот в этом вот цикле:

C
1
2
3
4
5
6
7
8
9
printf("Изменненый порядок букв: ");
    for (j = 0; j < arr[j]; j++)
    {
        t = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = t;
        printf("%c", arr[j]);
 
    }
Про размер вам уже сказали, т.е. условие j < arr[j] является неправильным. Но здесь еще две ошибки.
Во-первых, вы несколько раз вычисляете j + 1, лучше сделать рассчет в отдельной переменной, так вы уменьшите число вычислений.

Во-вторых, ошибка в строке arr[j] = arr[j + 1];
у вас есть массив:
arr[0] = 'a';
arr[1] = 'b';
arr[2] = 'c';
arr[3] = 'e';
вы хотите поменять местами соседние элементы и таким образом перевернуть массив задом наперед. Плюс, вывести его на экран.
Для того, чтобы вывести все элементы массива на экран вам придется использовать цикл:
for(j = 0; j < 4; j++), т.е. j будет поочередно принимать значения от 0 до 4, при этом, как только j станет равно 4, цикл завершится. И вроде бы все хорошо, но! Что будет происходить вот в этой строчке: arr[j] = arr[j + 1];

Давайте посмотрим:

1 шаг цикла, j = 0
arr[0] = arr[1];

2 шаг цикла, j = 1
arr[1] = arr[2];

3 шаг цикла, j = 2
arr[2] = arr[3];

4 шаг цикла, j = 3
arr[3] = arr[4];

5 шаг цикла, j = 4
конец цикла.

Ничего странного не заметили? Четвертый шаг цикла, в ячейку arr[3] записывается содержимое ячейки 4, но у нас в массиве нет такой ячейки! Посмотрите на массив как следует, последняя ячейка arr[3] = 'e';

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

Второй минус этого цикла в том, что вы делаете 4 шага, в каждом из которых совершаете по 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
#include <stdio.h>
#include <locale.h>
 
 
int main(void)
{
    setlocale(LC_ALL, "");
 
    int i, j, t;
    int n = 4;          // размер массива
    char arr[] = { 'a', 'b', 'c', 'd' };
 
    printf("Исходный порядок букв: ");
    for (i = 0; i < n; i++)
        printf("%c", arr[i]);
 
    printf("\n");
 
    printf("Изменненый порядок букв: ");
    for (i = 0; i < (n-1); i++)
    {
        j = i + 1;
        t = arr[i];
        arr[i] = arr[j];
        arr[j] = t;
        printf("%c", arr[i]);
    }
 
    printf("%c\n",arr[i]);
 
    return 0;
}
Так же рекомендую подумать над тем, как можно сократить число перестановок при развороте массива? Вы меняете соседние элементы, а что если менять первый и .. ?

Да, думаю тут уже понятно, что на каждом шаге цикла вычислять n-1 это тоже не дело, рекомендую подумать и над этим.
1
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
10963 / 6928 / 1635
Регистрация: 25.07.2009
Сообщений: 12,613
02.02.2018, 23:32 6
Цитата Сообщение от stake-k26 Посмотреть сообщение
char *locale = setlocale(LC_ALL, "");
замените на
setlocale(LC_ALL, "");
Плохой совет. Всегда сто'ит проверять, что возвращают функции.
1
1480 / 886 / 573
Регистрация: 25.04.2016
Сообщений: 2,459
02.02.2018, 23:43 7
easybudda, и в каком месте кода тут происходит проверка? А коль проверки изначально нет, то и заморачиваться не вижу смысла.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
10963 / 6928 / 1635
Регистрация: 25.07.2009
Сообщений: 12,613
02.02.2018, 23:50 8
Цитата Сообщение от stake-k26 Посмотреть сообщение
и в каком месте кода тут происходит проверка? А коль проверки изначально нет, то и заморачиваться не вижу смысла.
Нет её там. Но правильным советом было бы её добавить.
1
1480 / 886 / 573
Регистрация: 25.04.2016
Сообщений: 2,459
03.02.2018, 00:04 9
easybudda, согласен, но, судя по всему человек еще только-только с массивами разбирается, а мы ему сразу космическую станцию по всем стандартам инженерного дела будем городить? А он вообще после этого код прочитает? Я не уверен.

Добавлено через 8 минут
Мм, как бы правильнее сказать? Это все верно, конечно же, но новички обычно приходят с какими-то своими вопросами, возможно эти вопросы возникли в ходе самостоятельного изучения языка "по книжке", возможно курс обучения задается преподавателем - этого мы не знаем. Но если автор выкладывает свой код, то по нему уже более-менее можно определить уровень знаний и навыков. И если я вижу, что о выделении памяти в коде ни слова, то не вижу смысла скакать вперед паровоза и сообщать новичку о том, что есть такие штуки как стек, куча, очередь и прочее, зачем? Он ведь не об этом спрашивал. Его волнует какой-то свой вопрос. И отвечать нужно именно на него.
1
easybudda
03.02.2018, 00:28
  #10

Не по теме:

Вместо трёх строчек

C
1
2
3
4
if ( ! locale ) {
    fprintf(stderr, "Can't set locale!\n");
    return 1;
}
История целая с прологом и эпилогом...

0
1480 / 886 / 573
Регистрация: 25.04.2016
Сообщений: 2,459
03.02.2018, 00:52 11
easybudda, ничего не забыли? А как на счет wchar_t? Вы же вроде как за локализацию взялись, ну так и бейтесь до победного.

Еще не помешает определить текущую локализацию, и не забыть ее потом вернуть... если уж мы говорим о том, что "правильно"
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
10963 / 6928 / 1635
Регистрация: 25.07.2009
Сообщений: 12,613
03.02.2018, 02:14 12
Цитата Сообщение от stake-k26 Посмотреть сообщение
Еще не помешает определить текущую локализацию, и не забыть ее потом вернуть... если уж мы говорим о том, что "правильно"
По-хорошему бы да, только без кавычек. Другое дело - здесь и локализация-то не нужна по сути.

Цитата Сообщение от stake-k26 Посмотреть сообщение
А как на счет wchar_t?
От системы зависит. В Windows cp1251 однобайтовая.
1
stake-k26
04.02.2018, 03:21
  #13

Не по теме:

easybudda, вообще-то кавычки там стоят не случайно и вполне обоснованно. Согласно проблемы самоприменимости в общем случае и теореме Райса в частности, для решения любой задачи в программировании существует n-ое число алгоритмов. При этом, среди всех этих алгоритмов из числа n не существует ни одного "правильного". Т.е. любой "правильный" алгоритм решения будет неправильным или недостаточно правильным с точки зрения другого алгоритма, который решает ту же самую задачу. И наоборот, этот самый другой алгоритм будет неправильным с точки зрения первого. Таким образом в природе просто не существует "правильных" алгоритмов или "правильных" программ.

0
952 / 689 / 228
Регистрация: 30.06.2015
Сообщений: 3,696
Записей в блоге: 37
04.02.2018, 11:15 14
Цитата Сообщение от stake-k26 Посмотреть сообщение
Т.е. любой "правильный" алгоритм решения будет неправильным или недостаточно правильным с точки зрения другого алгоритма, который решает ту же самую задачу. И наоборот, этот самый другой алгоритм будет неправильным с точки зрения первого. Таким образом в природе просто не существует "правильных" алгоритмов или "правильных" программ.
«Алгоритм — это конечный набор правил, который определяет последовательность операций для решения конкретного множества задач и обладает пятью важными чертами: конечность, определённость, ввод, вывод, эффективность». (Д. Э. Кнут)
А так, как алгоритм можно выразить через машину Тьюринга, т. е. посредством конечного автомата, под который подведена серьёзная математическая база, то существует правильный или истинный алгоритм, не с точки зрения других каких-то алгоритмов, а с точки зрения математической модели, которая описывает конечный автомат.
1
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
10963 / 6928 / 1635
Регистрация: 25.07.2009
Сообщений: 12,613
04.02.2018, 13:51 15
stake-k26, демагогия сплошная. Есть алгоритм - последовательность шагов для решения задачи. А есть методика написания устойчивого кода. И вот к ней надо привыкать чем раньше, тем лучше. Хотите, чтобы программы вели себя предсказуемо - соблюдайте ряд правил, среди которых как-раз проверка возвращаемых функциями значений, восстановление изменённых параметров и прочее, прочее...
2
1480 / 886 / 573
Регистрация: 25.04.2016
Сообщений: 2,459
05.02.2018, 01:54 16
Цитата Сообщение от easybudda Посмотреть сообщение
А есть методика написания устойчивого кода.
Тремя постами выше, вы сами пришли к выводу, что "здесь и локализация-то не нужна по сути.",- так о чем вообще речь? Чем меньше операций в коде, тем устойчивее код. Полностью выкидываем локализацию, и все работает точно так же. Все верно. И никакая проверка даром не нужна. Т.е. она нужна, конечно, но точно не здесь.

CoderHuligan, вы не разобрались в сути вопроса и полезли в какие-то кусты вести партизанские войны за правое дело. Нет, я конечно, искренне желаю вам всяческих успехов в этом непростом деле, но не более.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.02.2018, 01:54

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Как организовать вывод переменных посредством printf
Интересует такой нюанс. Как организовать вывод этих переменных таким образом? т.е....

Разный вывод (printf) табуляции (\t) ветвлений (if-if-if-else) и (if-elseif-elseif-else)
Почему результатом выполнения нижеследующего кода при вводе, например: &quot;qweqwe&quot; консоль (linux)...

Указатели и printf
Здравствуйте. Простой вопрос, почему y и func(p_x, p_y) выводит одинаковое значение? #define...

Функция printf()
Когда делаешь ошибку в функции printf() , показывает что в файле stdio.h вот так выглядит создание...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.