Возможные ошибки при работе со строками — КиберПедия 

История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...

Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...

Возможные ошибки при работе со строками

2020-08-21 188
Возможные ошибки при работе со строками 0.00 из 5.00 0 оценок
Заказать работу

Основные ошибки при работе с С-строками происходят из-за отсутствия понимания специфики описания строк (строка-массив или строка-указатель)

//пример_4

int main ()                               

{

char msg[10];              //определение строки-массива

// msg="hello";             // error!!! пытаемся изменить указатель-константу!!!

strcpy_s (msg, "hello");   // ok!!! заполнение строки копированием!!!

 

char *name;            //определение указателя на char

// scanf ("%s", name);  // error!!! место под строку-указатель не выделено!!!

name = (char*) malloc(10); // ok!!! присваивание указателю адреса динамической строки

                        // или name = new char[10];   

printf ("name?");

scanf ("% s ",name);    //ввод строки, перед именем переменной не ставится  символ &

                      // ввод выполняется до первого пробельного символа

printf ("%s%s", msg, name);

_getch();

return 0;

}

Так как имя строки-массива – это указатель-константа, то нельзя выполнить присваивание:

char array[20];

//array = "Literal of string"; // error!!!

Заполнить строку-массив можно с использованием функции копирования (что мы видели в примере: strcpy _ s (msg, "hello");).

 

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

Ввод-вывод строк

Для ввода-вывода С-строк используются функции printf (),scanf (),gets() и puts(), унаследованные из библиотеки С. Функция gets(s) читает символы с клавиатуры, в том числе и пробелы (до символа новой строки), и помещает их в строку, завершая ее 0-символом; функция puts(s) выводит строку, заменяя 0-символ символом новой строки.

// С-ввод строки до первого пробельного символа                        

int main()

{

const int MAX = 80;             

char str[MAX];     // строка-массив                

printf ("Enter a string: ");

scanf ("%s", str);    //odin_dwa адрес переменной здесь не указываем

printf ("%s", str);      //odin_dwa

printf ( "%3s\n", str); //3 – минимальный размер поля вывода: odin_dwa

printf ( "%10.2s\n", str); //   od выравнивание вправо и 2 символа                 

printf ( "%-10.2s\n", str); //od    выравнивание влево и 2 символа     

  

printf ( "string?\n" );

scanf ( "%s", str);  //вводим: odin dwa, но вводится только odin (до пробела)

printf ( "%s\n", str); //в буфере ввода остался «хвост» dwa

// fflush (stdin);    // для корректной дальнейшей работы scanf ()
                          // требуется очистка буфера ввода: fflush (stdin);                        

  printf ( "string?\n" );

scanf ( "%s", str);

printf (" %s\n", str);                  

_getch();

return 0;

}

  

  

// С-ввод строки с пробелами                        

int main()

{

const int MAX = 10;             

char str[MAX];     // строка-массив                

printf ("Enter a string: ");

gets(str);          //ввод строки: odin dwa      

puts(str);          //вывод строки: odin dwa      

_getch();

return 0;

}

 

// посимвольный ввод строки в стиле С

int main()

{

const int MAX = 10;             

char str[MAX];           // строка-массив                

printf ("Enter a string: ");

for (int i=0; i<MAX; i++)        

scanf ("% c ", & str[i]);          //ввод символов 12345678 9 9                              

str[MAX-1]='\0';

printf ("%s", str);       //вывод строки 12345678 9

  

int i=0;

printf ("\nEnter a string: ");

while ((str[i] = _getch())!=13) // или!= ‘\r’ посимвольный ввод

           _putch (str[i++]); // посимвольный вывод

str[i] = '\0';                           // завершение строки

_putch ('\n'); _putch ('o'); _putch ('k');

printf ("\n%s", str);        //вывод строки    

  

_getch();

return 0;

}

    

Для ввода-вывода С-строк в стиле С++ используются известные нам объекты cin и cout.

//ввод строки до первого пробельного символа                         

int main()

{

const int MAX = 80;             

char str[MAX];     // строка-массив            

cout << "Enter a string: ";

cin >> str;        //ввод строки

cout << "You entered: " << str << endl; //вывод строки

_getch();

return 0;

}

 

// посимвольный ввод строки

int main()

{

const int MAX = 10;             

char str[MAX];     // строка-массив                

cout << "Enter a string: ";

for (int i=0; i< MAX-1; i++)               

               cin >> str[i];        //ввод символов 123456789 9                              

str[MAX-1]='\0';

cout << "You entered: " << str << endl;    //вывод строки: 123456789

_getch();

return 0;

}

 

Для ввода любых символов, включая пробельные, используются методы get() и get(c) класса istream, объектом которого является cin:

char c, d, e;

c=cin.get(); //возвращается код извлеченного из потока символа или EOF

cin.get(d);  //извлеченный из потока символ записывается в переменную-аргумент

cin.get(e);

 

// посимвольный ввод строки с использованием метода get()

int main()

{

const int MAX = 10;             

char str[MAX];     // строка-массив                

cout << "Enter a string: ";

for (int i=0; i< MAX-1; i++)

            cin. get (str [ i ]); //ввод без пробелов символов 12345 9                             

str[MAX-1]='\0';

cout << "You entered: " << str << endl; //вывод строки 12345 9

_getch();

return 0;

}

 

Для ввода строки из нескольких слов используются методы getline () или get () объекта cin:

 

// ввод строки из нескольких слов с использованием метода getline()

int main()

{

const int MAX = 80;             

char str[MAX];                     

cout << "\nEnter a string: ";

cin.getline (str, MAX); //ввод строки в str

                         //символ ‘\n’ считывается (удаляется) из потока ввода

                         //и вместо него в строковую переменную записывается ‘\0’

cout << "You entered: " << str << endl;

 

cin.get (str, MAX); // ввод строки в str

                    //символ ‘\n’ остается в потоке

                    //в строковую переменную добавляется ‘\0’

 

cout << "You entered: " << str << endl;

_getch();

return 0;

}

// ввод нескольких строк, завершающихся < enter >, в качестве одной строки

const int MAX = 2000;               

char str[MAX];                      

int main()

{

cout << "\nEnter a string:\n";

cin.get (str, MAX, ' $ ');     //ввод всех строк завершается символом $

cout << "You entered:\n" << str << endl;

_getch();

return 0;

}      

 

 В этом случае можно ввести несколько строк, завершающихся <enter>, и только затем набрать символ $ (все строки будут восприняты как одна строка):

Enter a string:

qwert

12345

qwert $

You entered:

qwert

12345

qwert

 

Обратите внимание на «плохую» работу метода get() при вызове его с двумя аргументами два раза подряд:

char s[10];

int n=5;

cin.get (s, n);         //1 вводим 123<enter>,‘\n’остается в потоке ввода

cout << s << endl;      //2 выводит 123

cin.get (s, n);         //3 считывает пустую строку

cout << s << endl;      //4   выводит пустую строку

cin.get (s, n);         //5   считывает пустую строку

cout << s << endl;      //6   выводит пустую строку

cout << "end" << endl;  //7   выполняется!!!

Результат работы:

123

123

 

 

end

 

За выводом в операторе //2 сразу последует сообщение “end”, выведенное оператором //7. Это происходит из-за символа ‘\n’, оставленного в потоке ввода первым вызовом метода get(), т.е. оператором //1. Поэтому операторами //3 и //5 будут считаны (и, соответственно) выведены на экран пустые строки.

Удалить символ ‘\n’ из входного потока можно путем вызова метода get() без параметров cin. get():

char s[10];

int n=5;

cin. get (s, n);     //1 вводим 123<enter>,‘\n’остается в потоке ввода

cout << s << endl;      //2 выводит 123

cin.get ();                //удаляем ‘\n’ из входного потока 

cin. get (s, n);          //3 вводим 234<enter>,‘\n’остается в потоке ввода

cout << s << endl;      //4 выводит 234

cin.get ();                 //удаляем ‘\n’ из входного потока

cin.get (s, n);          //5

cout << s << endl;      //6

cout << "end" << endl;     //7

Результат работы:

123

123

234

234

345

345

end

Еще лучше – использовать в таких случаях метод getline().

 

Следующий цикл обеспечивает ввод символов до нажатия ctrl + z – признака конца файла  

char c;

while ((c=cin.get())!=EOF) { //ввод символов, выход из цикла – ctrl + z – признак конца файла  

 cout << c;           

}

 

Для ввода нескольких С-строк можно использовать метод getline() в заголовке цикла:

int main()

{

const int n = 80;

char s[n];

while (cin.getline(s, n)) { //ввод строки в s, выход из цикла – ctrl+z – признак конца файла

 cout << s << endl;     //вывод строки

                   //………. обработка строки

 }

 _getch();     

 return 0;

 }

преобразование значения базового типа в С-строку

Функция С sprintf() аналогична printf(), однако выводит данные в строку-буфер.

 

char buf[20];     

  

int i=22222;

sprintf_s(buf, "% 7d ", i); //вывод переменной i типа int в строку-буфер buf,

cout << buf<< endl;    //длина которой равна 7: ” 22222”

 

sprintf_s(buf, "% 5 d ", i); //вывод переменной i типа int в строку-буфер buf,

cout << buf<< endl;    // длина которой равна 5: ”22222”

 

char c='a';    

sprintf_s(buf, "% 7 c ", c); //вывод переменной c типа char в строку-буфер buf,

cout << buf<< endl;  // длина которой равна 7: ” a”

 

sprintf_s(buf, "% c ", c); //вывод переменной c типа char в строку-буфер buf,

cout << buf<< endl;  // длина которой равна 1: ”a”

 

double d=1.23;

sprintf_s(buf, "% 5 f ", d); //вывод переменной d типа double, длина которой

cout << buf<< endl;  // равна 8: ”1.230000”, в строку-буфер buf

sprintf_s(buf, "% 9 f ", d); //вывод переменной d типа double (длина 8)в строку-буфер

cout << buf<< endl;  // buf длины 9:” 1.230000”

sprintf_s(buf, "% 11f ", d); //вывод переменной d типа double в строку-буфер buf

cout << buf<< endl;  // длины 11: ” 1.230000”


Поделиться с друзьями:

История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...

Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...

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

Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.057 с.