2014 dxdy logo

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

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




На страницу 1, 2  След.
 
 printf символа в Си
Сообщение15.12.2023, 23:04 
Подскажите, пожалуйста, почему команда 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 
Потому что %s ждёт строку, а они в C заканчиваются нулём, в массиве же work[] нуля нет, вот и печатается дальше вплоть до ближайшего нуля (в конце строки warm).
Для печати символов (по одному разумеется) есть %c.

 
 
 
 Re: printf символа в Си
Сообщение15.12.2023, 23:23 
Я добавил элемент "\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 
Xo4y3HaTb в сообщении #1622529 писал(а):
Но как понять что в массиве символов work нет нуля, а в конце строки warm есть?
Первое очевидно - вы же его полностью задали, а второе - ну например посмотреть размер warm и последний элемент. Или почитать про методы хранения данных (конкретно символов и строк) в памяти, стандарт или любой учебник.

-- 15.12.2023, 23:30 --

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

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

 
 
 
 Re: printf символа в Си
Сообщение16.12.2023, 00:41 
Признаться сто лет не смотрел в учебники, так что даже и не подскажу. Может ещё кто посоветует.
В принципе часть информации есть и в вики.

 
 
 
 Re: printf символа в Си
Сообщение16.12.2023, 00:48 
Аватара пользователя
cppreference.com ‐ вроде бы есть тьюториалы...

 
 
 
 Re: printf символа в Си
Сообщение16.12.2023, 00:56 
От так надо делать:

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

 
 
 
 Re: printf символа в Си
Сообщение16.12.2023, 01:31 
Всем спасибо за ответы!! Почитаю и вики, и cppreference.com. Спросил про учебник т.к. думал может есть "классические" какие-нибудь как в математике)

 
 
 
 Re: printf символа в Си
Сообщение16.12.2023, 02:41 
Аватара пользователя
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 
Xo4y3HaTb в сообщении #1622535 писал(а):
почитать учебник. Не могли бы посоветовать какой-нибудь?
На данном этапе советую почитать любой. Я в своё время читал любой учебник. По крайней мере, этот вопрос там описан.

 
 
 
 Re: printf символа в Си
Сообщение16.12.2023, 15:44 
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 
Запуская код ниже я каждое из 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 
Попробуйте написать 10 чисел через пробел и только потом нажать Enter.

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

 
 
 [ Сообщений: 18 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group