Как ввести строку с пробелами в c char
Перейти к содержимому

Как ввести строку с пробелами в c char

  • автор:

Вставить в строку пробелы с конца

Суть в том, что надо вставить пробелы в массив типа char с конца через каждые 3 символа, чтобы введя 1234567890, на выходе получалось 1 234 567 890. Я смог только обратится к концу массива, однако как вставить пробелы я без понятия. Буду благодарен за любую помощь

int main() < setlocale(0, ""); srand(time(0)); const int size = 80; char num[size]; cout system("pause"); return 0; > 

Отслеживать
219k 15 15 золотых знаков 119 119 серебряных знаков 230 230 бронзовых знаков
задан 15 дек 2020 в 6:47
bruhmomentum bruhmomentum
59 1 1 серебряный знак 9 9 бронзовых знаков

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Вот пример кода с комментариями:

int real_size = strlen(num); //Количество отступов int count = real_size / 3 + (bool)(real_size % 3) - 1; //Обрезаем нашу новую строку num[real_size + count] = '\0'; //Проходим по всем тройкам с конца, кроме первой for (int i = real_size - 1; i >= 3; i -= 3) < //Можно без цикла просто перенести три символа назад на count позиций for (int j = 0; j

Объясню идею через пример.

Есть строка 1234567 у нее count = 2 т.к. в итоге получим 2 пробела. И первую с конца тройку мы сместим сначала на 2 позиции. Т.к. мы знаем что будет еще одна тройка, которую мы уже сместим на 1 позицию. Получается каждую следующую тройку мы будем смещать на 1 позицию меньше, чем предыдущую. Надеюсь понятно объяснил.

Как ввести строку с пробелами в c char

Сообщение от forsaken66

#include "stdafx.h" #include "iostream" #include "conio.h" #include "stdio.h" #include "string" using namespace std; char *s=""; int main () < cout 

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

читайте ошибки компилятор которые выдает

error C2661: gets: нет перегруженной функции, принимающей 2 аргументов

вот исправил чуток

#include "iostream" #include "conio.h" #include "stdio.h" #include "string" using namespace std; int main ()

Последний раз редактировалось kedbl4; 19.11.2009 в 12:15 . Причина: неправильно ввел

Как ввести в cin строки с пробелами в С++

По умолчанию cin (стандартный ввод) в С++ считывает данные до первого пробела. Рассмотрим способы, с помощью которых мы можем передать через стандартный ввод строку, содержащую один или нескольких пробелов, чтобы эта строка могла быть присвоена в качестве значения переменной в программе.

cin по умолчанию пропускает все белые пробелы (пробелы, табуляции, новые строки и т. д.). Вы можете либо изменить его поведение, либо использовать немного другой механизм.

Рассмотрим небольшую программу, которая просит пользователя ввести имя и после этого сразу же отображает введённую строку на экране. Приведённый код работает так, как ожидается, если вводимые данные не содержат пробелов:

#include using namespace std; int main() < string line; cout > line; cout

Для запуска этого кода сохраните его в файл test.cpp и скомпилируйте:

g++ test.cpp

Запуск скомпилированного файла:

./a.out

Попробуем ввести строку с пробелами:

Как можно увидеть, из введённой строки «Алексей Милосердов», сохранилось только часть до пробела, то есть «Алексей».

Чтение строки с getline

getline читает символы из входного потока и помещает их в строку — именно это нам и нужно. getline (как и использование строки), требует указать заголовок #include . Отредактируем наш код:

#include #include using namespace std; int main()

Как можно убедиться, теперь строка считалась полностью, вместе с пробелами.

Изменение поведения cin с помощью noskipws

Как мы уже выяснили, по умолчанию cin пропускает все белые пробелы (пробелы, табуляции, новые строки и т. д.). Чтобы изменить его поведение, используйте манипулятор noskipws следующим образом:

cin >> noskipws >> line;

noskipws включает пропуск начальных пробелов с помощью форматированных функций ввода (по умолчанию включено). Не влияет на вывод.

То есть noskipws не поможет нам передать через стандартный ввод строки, содержащие в себе пробелы, кроме тех случаев, когда пробелы стоят в начале строки.

Чтобы стало понятнее, рассмотрим следующий код:

#include #include using namespace std; int main() < char c1, c2, c3; istringstream("a b c") >> c1 >> c2 >> c3; cout > noskipws >> c1 >> c2 >> c3; cout

В результате работы этого кода будет выведено:

Поведение по умолчанию: c1 = a c2 = b c3 = c Поведение с noskipws: c1 = a c2 = c3 = b

Смотрите также онлайн учебник «Основы С++».

Особенности работы со строками в языке Си

Неформатированные ввод из стандартного потока и вывод в стандартный поток

С помощью функции printf() можно легко вывести на экран строку, содержащую пробелы:

printf("%s", "Hello world");

Ввести строку с пробелами уже сложнее. Для scanf() любой символ пустого пространства является сигналом завершения ввода очередных данных, если только не производится считывание самого символа. Чтобы ввести строку произвольной длины, содержащую пробелы в неизвестных местах, приходится использовать шаблон:

scanf("%[^'\n']", str);

Также на помощь может прийти функция getchar() , осуществляющая посимвольный ввод данных:

#include int main() { char str[20], i; for (i = 0; (str[i] = getchar()) != '\n'; i++); str[i] = '\0'; printf("%s\n", str); }

В заголовке цикла getchar() возвращает символ, далее записываемый в очередную ячейку массива. После этого элемент массива сравнивается с символом '\n'. Если они равны, то цикл завершается. После цикла символ '\n' в массиве "затирается" символом '\0'. В условии цикла должна быть также предусмотрена проверка на выход за пределы массива; чтобы не усложнять пример, опущена.

Однако в языке программирования C работать со строками можно проще. С помощью функций стандартной библиотеки gets() и puts() получают строку из стандартного потока и выводят в стандартный поток. Буква s в конце слов gets и puts является сокращением от слова string (строка).

В качестве параметров обе функции принимают указатель на массив символов (либо имя массива, либо указатель).

Функция gets() помещает полученные с ввода символы в указанный в качестве аргумента массив. При этом символ перехода на новую строку, который завершает ее работу, игнорируется.

Функция puts() выводит строку на экран и при этом сама добавляет символ перехода на новую строку. Простейший пример использования этих функций выглядит так:

#include int main() { char str[100]; gets(str); puts(str); }

При компиляции данной программы появляется предупреждение об опасности использования gets (но программа скомпилируется и будет работать). Вместо нее рекомендуют использовать функцию fgets . Однако последней кроме указателя на строку также надо передать лимит количества считываемых символов и из какого потока ввода поступают данные. В данном случае ‒ из стандартного ‒ stdin :

#include #define N 100 int main() { char str[N]; fgets(str, N, stdin); puts(str); }

При этом в строку помещается и символ перехода на новую строку ‒ '\n'. И только после него символ конца строки ‒ '\0'. Если переход не нужен, от него можно избавиться так:

str[strcspn(str, "\n" )] = '\0';

Итак, если вы работаете со строками, а не другими типами данных, при этом нет необходимости выполнять их посимвольную обработку, то может быть удобнее пользоваться функциями puts и fgets .

Массив символов и указатель на строку

Как мы знаем, строка представляет собой массив символов, последний элемент которого является нулевым символом по таблице ASCII, обозначаемым '\0'. При работе со строками также как с численными массивами можно использовать указатели. Мы можем объявить в программе массив символов, записать туда строку, потом присвоить указателю адрес на первый или любой другой элемент этого массива и работать со строкой через указатель:

char name[30]; char *p; printf("Введите имя и фамилию: "); fgets(name, sizeof(name), stdin); printf("Имя: "); for (p = name; *p != ' '; p++) putchar(*p); printf("\nФамилия: "); puts(p + 1);

В заголовке цикла указателю сначала присваивается адрес первого элемента массива, его значение увеличивается до тех пор, пока не встретится пробел. В итоге указатель указывает на пробел, и мы можем получить с его помощью вторую часть строки.

Иногда в программах можно видеть такое объявление и определение переменной-указателя:

char *strP = "Hello World!";

Строку, которая была присвоена не массиву, а указателю, также можно получить, обратившись по указателю:

puts(strP);

Но давайте посмотрим, что же все-таки происходит, и чем такая строка, присвоенная указателю, отличается от строки, присвоенной массиву.

Когда в программе определяются данные и объявляются переменные, то под них отводится память. При этом данные, которые не были присвоены переменным, поменять в процессе выполнения программы уже нельзя.

Что происходит в примере? В программе вводится строковый объект, который по сути является строковой константой (литералом). Ссылка на первый элемент этой строки присваивается указателю. Мы можем менять значение указателя сколько угодно, переходить к любому из элементов константного массива символов или даже начать ссылаться на совершенно другую строку. Но вот поменять значение элементов строки не можем. Это можно доказать таким кодом:

char *strP; // работает, но строку нельзя изменить strP = "This is a literal"; puts(strP); printf("%c\n",strP[3]); strP[3] = 'z'; // не получится

В последней строке кода возникнет ошибка (при выполнении программы), т.к. совершается попытка изменить строку-константу.

Тем более нельзя делать так:

char *strP; // ошибка сегментирования scanf("%s",strP); 

В данном случае память не была выделена под массив символов, который мы пытаемся получить функцией scanf() ; память была выделена только под указатель. Поэтому записать строку просто некуда. Другое дело, если память была выделена с помощью объявления массива, после чего указателю был присвоен адрес на этот массив:

char str[12]; char *strP; strP = str; // память резервируется под массив ранее gets(strP); puts(strP);

Итак, если вам требуется в программе неизменяемый массив символов, то можете определить его через указатель.

Передача строки в функцию

Передача строки в функцию ничем не отличается от передачи туда массива чисел:

char name[30]; char *p; printf("Введите имя и фамилию: "); fgets(name, sizeof(name), stdin); printf("Имя: "); for (p = name; *p != ' '; p++) putchar(*p); printf("\nФамилия: "); puts(p + 1);

В этом примере функция change принимает в качестве аргумента указатель на символ. В теле функции значение указателя инкрементируется, указывая на следующий символ массива. В теле цикла инкрементируется значение, которое находится по адресу, который содержит указатель.

Объявите в программе три массива символов. Данные для двух из них получите с помощью вызовов функции fgets() . Третий массив должен содержать результат конкатенации (соединения) двух введенных строк. Напишите функцию, которая выполняет конкатенацию строк.

Массив строк и массив указателей

Рассмотрим более сложный пример. Допустим, у нас есть набор строк. Требуется выполнить сортировку строк по возрастанию по признаку длины: сначала вывести самые короткие строки, затем более длинные.

Набор строк можно представить как двумерный массив, т.е. массив, состоящий из одномерных массивов, где каждый одномерный массив — это строка символов:

char str[][10] = {"Hello", "World", ". ", "&&&"};

Представьте себе, что значит выполнить сортировку строк. Это значит, надо поменять местами содержимое множества ячеек памяти. Это достаточно трудоемкая для компьютера работа, особенно если строк очень много. Однако можно поступить по-иному. Достаточно создать массив указателей, каждый элемент которого будет указывать на соответствующую ему строку первого массива. Далее выполнить сортировку указателей, что несомненно быстрее. Конечно, сам массив строк отсортирован не будет, однако благодаря указателям у нас будет хранится отсортированный "срез" массива:

Сортировка строк через массив указателей

#include #include #define N 6 #define M 30 void sortlen(char *s[]); int main() { char strings[N][M]; char *p[N]; for (int i = 0; i  N; i++) { fgets(strings[i], M, stdin); p[i] = &strings[i][0]; } printf("\n"); sortlen(p); for (int i = 0; i  N; i++) { printf("%s", p[i]); } } // **s == *s[] - массив указателей void sortlen(char **s) { int i, j; char *str; for (i = 0; i  N-1; i++) for (j = 0; j  N-i-1; j++) if (strlen(s[j]) > strlen(s[j+1])) { str = s[j]; s[j] = s[j+1]; s[j+1] = str; } }

Примечания к программе:

  • Функция strlen объявлена в заголовочном файле string.h . Она возвращает длину строки без учета завершающего нулевого символа.
  • Сортировка выполняется методом пузырька: если длина строки, на которую ссылается следующий указатель массива s , меньше длины строки под текущим указателем, то значения указателей меняются.
  • Выражение p[i] = &strings[i][0] означает, что элементу массива указателей присваивается ссылка на первый символ каждой строки.

Напишите программу, которая сортирует строки по алфавиту. Для упрощения задачи пусть сортировка выполняется только по первым буквам строк (если первые буквы слов одинаковы, то вторые и последующие символы проверять не надо).

Курс с решением задач:
pdf-версия

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *