2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 printf символа в Си
Сообщение15.12.2023, 23:04 


14/04/20
87
Подскажите, пожалуйста, почему команда printf мне выдаёт в консоль текст supskubidy, а не просто sup? Я ведь взываю к массиву под именем work. Где ошибка? Проверял на нескольких онлайн компиляторах
Код:
#include <stdio.h>
int main(){

    char work[] = {'s', 'u', 'p'};
    char warm[] = "skubidy";
   
    printf("%s\n", work);
    return 0;
}
       

 Профиль  
                  
 
 Re: printf символа в С
Сообщение15.12.2023, 23:07 
Заслуженный участник


20/08/14
11760
Россия, Москва
Потому что %s ждёт строку, а они в C заканчиваются нулём, в массиве же work[] нуля нет, вот и печатается дальше вплоть до ближайшего нуля (в конце строки warm).
Для печати символов (по одному разумеется) есть %c.

 Профиль  
                  
 
 Re: printf символа в Си
Сообщение15.12.2023, 23:23 


14/04/20
87
Я добавил элемент "\0" в массив work и получил результат который хотел. Но как понять что в массиве символов work нет нуля, а в конце строки warm есть?
Код:
#include <stdio.h>
int main(){

    char work[] = {'s', 'u', 'p', '\0'};
    char warm[] = "skubidy";
   
    printf("%s\n", work);
    return 0;
}
       


-- 15.12.2023, 23:24 --

Dmitriy40 в сообщении #1622527 писал(а):
Для печати символов (по одному разумеется) есть %c.
Хочется как раз не по одному символу, а целиком массив напечатать по одному имени.

 Профиль  
                  
 
 Re: printf символа в Си
Сообщение15.12.2023, 23:25 
Заслуженный участник


20/08/14
11760
Россия, Москва
Xo4y3HaTb в сообщении #1622529 писал(а):
Но как понять что в массиве символов work нет нуля, а в конце строки warm есть?
Первое очевидно - вы же его полностью задали, а второе - ну например посмотреть размер warm и последний элемент. Или почитать про методы хранения данных (конкретно символов и строк) в памяти, стандарт или любой учебник.

-- 15.12.2023, 23:30 --

Xo4y3HaTb в сообщении #1622529 писал(а):
Хочется как раз не по одному символу, а целиком массив напечатать по одному имени.
В массиве символов символ с кодом 0x00 вполне корректен, а вот как часть строки он недопустим (является признаком её конца). Если Вы 146% уверены что в массиве символов никогда не будет нулевых символов, то добавляйте его в конец и печатайте как строку, как и сделали.

 Профиль  
                  
 
 Re: printf символа в Си
Сообщение15.12.2023, 23:40 


14/04/20
87
Dmitriy40 в сообщении #1622530 писал(а):
Первое очевидно - вы же его полностью задали, а второе - ну например посмотреть размер warm и последний элемент. Или почитать про методы хранения данных (конкретно символов и строк) в памяти, стандарт или любой учебник.
В массиве символов символ с кодом 0x00 вполне корректен, а вот как часть строки он недопустим (является признаком её конца). Если Вы 146% уверены что в массиве символов никогда не будет нулевых символов, то добавляйте его в конец и печатайте как строку, как и сделали.
Признаться, с трудом понимаю о чём вы говорите. Видимо, мне действительно нужно почитать учебник. Не могли бы посоветовать какой-нибудь?

 Профиль  
                  
 
 Re: printf символа в Си
Сообщение16.12.2023, 00:41 
Заслуженный участник


20/08/14
11760
Россия, Москва
Признаться сто лет не смотрел в учебники, так что даже и не подскажу. Может ещё кто посоветует.
В принципе часть информации есть и в вики.

 Профиль  
                  
 
 Re: printf символа в Си
Сообщение16.12.2023, 00:48 
Заслуженный участник
Аватара пользователя


01/09/13
4656
cppreference.com ‐ вроде бы есть тьюториалы...

 Профиль  
                  
 
 Re: printf символа в Си
Сообщение16.12.2023, 00:56 


10/03/16
4444
Aeroport
От так надо делать:

TheRuinedMap, прийди!(те)

 Профиль  
                  
 
 Re: printf символа в Си
Сообщение16.12.2023, 01:31 


14/04/20
87
Всем спасибо за ответы!! Почитаю и вики, и cppreference.com. Спросил про учебник т.к. думал может есть "классические" какие-нибудь как в математике)

 Профиль  
                  
 
 Re: printf символа в Си
Сообщение16.12.2023, 02:41 
Аватара пользователя


28/10/21
100
Xo4y3HaTb в сообщении #1622529 писал(а):
Но как понять что в массиве символов work нет нуля, а в конце строки warm есть?


Путем чтения спецификации языка.

В конце строки work нет нуля потому, что вы его не указали в инициализаторе. Не указали - вот его и нет. Обратите внимание, что если бы вы явно указали размер массива work и сделали бы его побольше (например, work[10]), то те элементы массива, которым не хватило инициализаторов, были бы автоматически обнулены. Таким образом в массиве work появились бы замыкающие нули и при печати такого массива через %s выводилось бы просто sup. Но вы не указали размера массива work вообще. В таком случае этот размер будет автоматически вычислен на основе количества указанных инициализаторов. Вы указали три инициализатора - значит размер массива будет равен 3 и никакого замыкающего нуля в нем не будет.

В то же время грамматическая конструкция "skubidy" - это так называемый строковый литерал, т.е. последовательность символов, которая, согласно спецификации языка, неявно включает в себя символ '\0' в конце. То есть в объявлении массива warm, указанный вами инициализатор уже включает в себя замыкающий ноль. Размер инициализатора "skubidy" сам по себе равен 8 (попробуйте sizeof "skubidy"). Поэтому и размер массива warm, который вы тоже не указали, будет автоматически установлен равным 8 и этот массив будет проинициализирован всеми восемью символами строкового литерала "skubidy", включая замыкающий ноль.

P.S. Одной из особенностей языка С (и отличием от С++) является то, что вы можете "потерять" замыкающий ноль при инициализации массива warm, если явно укажете размер этого массива как 7.

 Профиль  
                  
 
 Re: printf символа в Си
Сообщение16.12.2023, 12:26 
Заслуженный участник


16/02/13
4194
Владивосток
Xo4y3HaTb в сообщении #1622535 писал(а):
почитать учебник. Не могли бы посоветовать какой-нибудь?
На данном этапе советую почитать любой. Я в своё время читал любой учебник. По крайней мере, этот вопрос там описан.

 Профиль  
                  
 
 Re: printf символа в Си
Сообщение16.12.2023, 15:44 


14/04/20
87
TheRuinedMap в сообщении #1622573 писал(а):
В конце строки work нет нуля потому, что вы его не указали в инициализаторе. Не указали - вот его и нет. Обратите внимание, что если бы вы явно указали размер массива work и сделали бы его побольше (например, work[10]), то те элементы массива, которым не хватило инициализаторов, были бы автоматически обнулены. Таким образом в массиве work появились бы замыкающие нули и при печати такого массива через %s выводилось бы просто sup.
Но вы не указали размера массива work вообще. В таком случае этот размер будет автоматически вычислен на основе количества указанных инициализаторов. Вы указали три инициализатора - значит размер массива будет равен 3 и никакого замыкающего нуля в нем не будет.
Это понял, в моём случае работает начиная с 4 (work[4]), т.к. элемента 3.
TheRuinedMap в сообщении #1622573 писал(а):
В то же время грамматическая конструкция "skubidy" - это так называемый строковый литерал, т.е. последовательность символов, которая, согласно спецификации языка, неявно включает в себя символ '\0' в конце. То есть в объявлении массива warm, указанный вами инициализатор уже включает в себя замыкающий ноль. Размер инициализатора "skubidy" сам по себе равен 8 (попробуйте sizeof "skubidy"). Поэтому и размер массива warm, который вы тоже не указали, будет автоматически установлен равным 8 и этот массив будет проинициализирован всеми восемью символами строкового литерала "skubidy", включая замыкающий ноль.
Проверил printf("%lu\n", sizeof(warm) выдаёт 8. Тоже понятно.
Спасибо большое за объяснение!

iifat

Хорошо!) Выбрал И.С. Солдатенко "Основы программирования на языке Си"

 Профиль  
                  
 
 Re: printf символа в Си
Сообщение16.12.2023, 19:34 


14/04/20
87
Запуская код ниже я каждое из 10 чисел ввожу в новой строке, а мне хочется вводить 10 чисел в одну строку через пробел. Подскажите, пожалуйста, где ошибка? \n же не стоит в команде scanf.
Код:
#include <stdio.h>
#define M 10
int main(){
    int arr[M];
    int i=0;
    for(i=0; i=<M-1; i++){
      scanf("%d ", &arr[i]);
    }
    return 0;
}

 Профиль  
                  
 
 Re: printf символа в Си
Сообщение16.12.2023, 20:18 
Заслуженный участник


12/08/10
1677
Попробуйте написать 10 чисел через пробел и только потом нажать Enter.

 Профиль  
                  
 
 Re: printf символа в Си
Сообщение16.12.2023, 20:45 


14/04/20
87
Null в сообщении #1622683 писал(а):
Попробуйте написать 10 чисел через пробел и только потом нажать Enter.
Получилось! Даже больше чем 10 получается, сколько угодно) Спасибо!

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 18 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group