LINUX.ORG.RU

Не определить конец строки в с++


0

0

По идее конец строки обуславливается нулевым символом. 
Однако на практике не получилось добиться этого. Я сделал массив
строк. Загоняю первую строку из этого большого массива в одномерный
массив строки. Конец первой строки, с которой работаю, думал
обозначить нулевым символом, но не тут то было.

#include<iostream>
using namespace std;
int main()
{
	char name[3][80]={
		{"hjjhhjkhkmhk"},
		{"kjjkjk kkjj ll"},
		{"jhhj sla lsds"}
	};
	char a[80];
	int j;
	
		for(j=0; j!=0; j++)
		{
			a[j]=name[0][j];
		}
	
	cout<<a;
}

Есть идеи? Ручное указание длинны строки работает.


Калькулятор купи.

anonymous
()

Вообще это не с++. Но ошибка в предложенном коде такая: надо сравнивать не с 0, а с '\0'

ftor
()

for(j=0; name[0][j] != 0; j++) {
a[j] = name[0][j];
}
a[j] = 0;

balodja ★★★
()

Открыл для себя strcpy и задание то решил, но вопрос как найти
последний (или предпоследний) символ каждой строки оставляю открытым
(почитаю сейчас ваши ответы, возможно он сам отпадёт. Спасибо. Готовая 
программа:

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	char name[3][80]={
		{"hjjhhjkhkmhk"},
		{"kjjkjk kkjj ll"},
		{"jhhj sla lsds"}
	};
	char a[80], b[80], c[80];
	
	strcpy(a, name[0]);
	strcpy(b, name[1]);
	strcpy(c, name[2]);
	
	
	cout<<a<<endl<<b<<endl<<c;
}

Wedge_Antilles
() автор топика
Ответ на: комментарий от Wedge_Antilles

Опять студенты-неучи...

Ваш код - не Си++, да и рано вам на нем писать, только бед натворите.

Выучите Си, хотя бы по классике Кернигана и Ритчи.

anonymous
()
Ответ на: комментарий от Wedge_Antilles

Теперь откройте для себя strlen(). А вообще да - настоятельно рекомендую приобрести книжку по С (Вам - любую) и уехать с ней на недельку в деревню, подальше от компьютера.

Dendy ★★★★★
()

for(j=0; name[0][j]!=0; j++)
{
a[j]=name[0][j];
}
a[j]=0;

AGUtilities ★★★
()

Ты не символ сравниваешь с нулем, а счетчик j.

Reset ★★★★★
()

> for(j=0; j!=0; j++)

Си не знаешь ты... Лекций учителя твоего ты много пропускал...

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

xydo ★★
()
Ответ на: комментарий от xydo

>> Си не знаешь ты...

ИМХО у человека не с Си проблемы, а вообще с пониманием того чего он хочет и как это сказать компилятору (независимо от ЯП) 8).

Deleted
()
Ответ на: комментарий от ftor

> Но ошибка в предложенном коде такая: надо сравнивать не с 0, а с '\0'

это один хрен. В данном случае хоть с NULL сравнивать можно(но ненужно). Просто NULL это указатель, '\0' символ, а 0 это int.

true_admin ★★★★★
()

Сделал окончательный вариант... что-то большеват.
Есть идеи по оптимизации?

Программа из массива строк с именами и фамилиями создаёт два:
один с именами, другой с фамилиями.

#include <iostream>
#include <cctype>
#include <cstring>
using namespace std;
int main()
{
	char all [3][80] = {
		{"famaly1 name1"},
		{"famaly2 name2"},
		{"famaly3 name3"}
	};
	char famaly[3][80];
	char name[3][80];
	int i,j,k=0,probel1,probel2,probel3; //i,j - счётчики обработки массивов
	int end1,end2,end3;
	for (i=0; i<3; i++)
	{
		for (j=0; all[i][j]; j++)
		{
			if (isspace(all[i][j])) //если программа встречает пробел, то:
			{
				k=k+1; //c помощью k считаем число пробелов между именем и фамилией
				if (k==1) probel1=j; //
				if (k==2) probel2=j; //запоминаем номера пробелов
				if (k==3) probel3=j; //

			}
		}
	}
	end1=strlen(all[0]); //
	end2=strlen(all[1]); //высчитываем длинну каждой строки в исходом массиве
	end3=strlen(all[2]); //

	//заносим фамилию первой строки из исходного массива в первую строку нового массива
	for(j=0; j<probel1; j++)
	{
		famaly[0][j]=all[0][j];
	}
	//заносим фамилию второй строки из исходного массива во вторую строку нового массива
	for(j=0; j<probel2; j++)
	{
		famaly[1][j]=all[1][j];
	}
	//заносим фамилию третьей строки из исходного массива в третью строку нового массива
	for(j=0; j<probel3; j++)
	{
		famaly[2][j]=all[2][j];
	}

	//выводим новый массив с фамилиями на экран
	for (i=0; i<3; i++)
	{
		for(j=0; famaly[i][j]; j++)
		{
			cout<<famaly[i][j];
		}
		cout<<endl;
	}
	
	cout<<endl;
	
	//заносим имя первой строки из исходного массива в первую строку нового массива
	for(j=(probel1+1), i=0; j<=end1; j++, i++)
	{
		name[0][i]=all[0][j];
	}

	//заносим имя второй строки из исходного массива во вторую строку нового массива
	for(j=(probel2+1), i=0; j<=end2; j++, i++)
	{
		name[1][i]=all[1][j];
	}

	//заносим имя третьей строки из исходного массива в третью строку нового массива
	for(j=(probel3+1), i=0; j<=end3; j++, i++)
	{
		name[2][i]=all[2][j];
	}

	//выводим новый с именами массив на экран
	for (i=0; i<3; i++)
	{
		for(j=0; name[i][j]; j++)
		{
			cout<<name[i][j];
		}
		cout<<endl;
	}

}

Wedge_Antilles
() автор топика
Ответ на: комментарий от imp

думаю, лошадь стоит пристрелить, чтоб не мучилась

dilmah ★★★★★
()
Ответ на: комментарий от Wedge_Antilles

Все это делается в 3 раза короче и в 3 раза яснее. А книжку по С действительно стоит прочесть... или программировать на Яве, Питоне или подобном.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

Все же я склоняюсь к тому же, что дилмах: Си тебе не стоит учить. Можешь выучить перл, там такое делается вообще в 3 строки, или даже в 1.

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

http://www.linux.org.ru/view-message.jsp?msgid=3152343

>У меня и так g++... А вот в институт поставить что-либо другое мне никто не даст.

Perl стоит в любом линуксе, изучи его -- там со строками очень легко, и прекрати мучить народ своим ужасным С-кодом.

(Чувак не осилил указатели)

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от www_linux_org_ru

Не не осилил, а ещё не дошёл до них. Это разное.

Wedge_Antilles
() автор топика
Ответ на: комментарий от Wedge_Antilles

char all [3][80] = {{"famaly1 name1"},
		    {"famaly2 name2"},
		    {"famaly3 name3"}};

char surnames[3][80];
char names[3][80];
char *ps = &surnames;
char *pn = &names;
char *pa = &all;
while(&all+3*80>pa){
  while((*ps++=*pa++) != ' '); // копируем фамилию
  while(*pn++=*pa++); // копируем имя 
}

зы. вся эта лабуда работать не обязана.

wfrr ★★☆
()

у O'reilly есть хорошая книжка C in the nut shell + рекомендую почитать gnu libc (glibc) с их сайта

AGUtilities ★★★
()

> По идее конец строки обуславливается нулевым символом.

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

P.S. Закидайте какашками - это винда.

Ian ★★
()
Ответ на: комментарий от samson

> такой for ниразу не выполниться

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

anonymous
()
Ответ на: комментарий от anonymous

> В Си++ NULL ≡ 0

Ох уж эти плюс-плюсники, не знал :)

true_admin ★★★★★
()
Ответ на: комментарий от Wedge_Antilles

>Есть идеи по оптимизации?

processOne :: String -> (String, String)
processOne str =
    (fst spanned, dropWhile (== ' ') $ snd spanned)
        where
          spanned = span (/= ' ') str

processList :: [String] -> [(String, String)]
processList = map processOne

jtootf ★★★★★
()
Ответ на: комментарий от anonymous

>В Си++ NULL ≡ 0

по-моему корректней сказать что литерал 0 всегда корректно приводится к нулевому указателю нужного типа; значение NULL я могу поменять на раз :)

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

Мои 5 копеек на CL (решение далеко от идеала): 

(defun parse-string-list (lst)
  (labels ((split-string (str) 
             (let ((pos (position #\Space str)))
               (list (subseq str 0 pos) (subseq str (+ pos 1))))))
    (mapcar #'split-string lst)))

Sectoid ★★★★★
()
Ответ на: комментарий от Sectoid

>(list (subseq str 0 pos) (subseq str (+ pos 1)))

пробел может быть больше чем один, оригинальная реализация это учитывает

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

Опс... Забыл. Тогда так:

(defun parse-string-list (lst)
  (labels ((split-string (str) 
             (let ((pos (position #\Space str)))
               (list (subseq str 0 pos) (string-trim '(#\Space) (subseq str pos))))))
    (mapcar #'split-string lst)))

Sectoid ★★★★★
()
Ответ на: комментарий от Sectoid

подогнал под твой вариант. надо будет в point-free перевести,
подумаю над этим :)

processList :: [String] -> [(String, String)]
processList list = map processOne2 list
    where processOne2 str = (fst spanned, dropWhile (== ' ') $ snd spanned)
              where
                spanned = span (/= ' ') str

jtootf ★★★★★
()
Ответ на: комментарий от Sectoid

$ cat txt.txt
famaly1 name1 famaly2 name2 famaly3 name3

$ cat txt.txt | xargs -n2 | awk -vSURNAMES=surnames -vNAMES=names '{ print $1 > SURNAMES; print $2 > NAMES }'


$ cat surnames
famaly1
famaly2
famaly3
$ cat names
name1
name2
name3

dilmah ★★★★★
()
Ответ на: комментарий от jtootf

#!/usr/bin/evn ruby

names=[]
famaly=[]
"famaly1 name1 famaly2 name2 famaly3 name3".scan(/([^ ]+) ([^ ]+)/).map{|f, n|
        names+=[n]
        famaly+=[f]
}
puts [names,famaly].each{|n| n.to_s + "\n"}

хотя может я уже сбился с мысли....

ASM ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.