Помощ! char в C++
14 отговора
535 прегледа
Помощ! char в C++
Налага ми се да поправя сорс на Си, където изобщо нямам опит. Става въпрос за нещо елементарно:
в променлива key от тип char стои 8 цифров ключ (например 0028345). Искам да създам поддиректория на директорията camDirName с име = на първите 5 цифри от ключа key (в случая - 00028345). Написала съм следния код (да уточня, че сорса трябва да се компилира с C++ 5.02 компилатора на Borland):
char camLocalDirName[5]; sprintf(camLocalDirName, "%s%s", key, "\0");
char camDirName[_pathlen]; sprintf(camDirName,"%s%s\\",path,camLocalDirName);
{
if (errno == ENOENT) //directory does not exist
{
if (mkdir(camDirName)) return 0;
}
}
E, да, ама тоя код създава поддиректорията 00028345, а не 00028, както на мен ми се иска. При проверката - camLocalDirName си съдържа "00028", ама какво става после при сливането - не знам.
Някой ако знае как да се справя - моля. Предпочитам решение без basic_string, ама ако не става - приема се и всяко други решение.
в променлива key от тип char стои 8 цифров ключ (например 0028345). Искам да създам поддиректория на директорията camDirName с име = на първите 5 цифри от ключа key (в случая - 00028345). Написала съм следния код (да уточня, че сорса трябва да се компилира с C++ 5.02 компилатора на Borland):
char camLocalDirName[5]; sprintf(camLocalDirName, "%s%s", key, "\0");
char camDirName[_pathlen]; sprintf(camDirName,"%s%s\\",path,camLocalDirName);
{
if (errno == ENOENT) //directory does not exist
{
if (mkdir(camDirName)) return 0;
}
}
E, да, ама тоя код създава поддиректорията 00028345, а не 00028, както на мен ми се иска. При проверката - camLocalDirName си съдържа "00028", ама какво става после при сливането - не знам.
Някой ако знае как да се справя - моля. Предпочитам решение без basic_string, ама ако не става - приема се и всяко други решение.
Re: Помощ! char в C++
greshkata e w pyrwiq red
zamenq sys slednite 3 i twa e to:
char camLocalDirName[200];
strcpy(camLocalDirName, key);
camLocalDirName[6] = 0;
zamenq sys slednite 3 i twa e to:
char camLocalDirName[200];
strcpy(camLocalDirName, key);
camLocalDirName[6] = 0;
Re: Помощ! char в C++
Probvai taka :
#include <string.h>
char camLocalDirName[6];
strncpy (camLocalDirName, key, 5);
camLocalDirName[5] = NULL;
..........
a ako izkash po twoia si na4in
moje taka i da stane
char camLocalDirName[9]; //ako dyljinata na key e 8 simwola (zaradi \0)
sprintf(camLocalDirName, "%s", key); // ako key e chislo izpolzwai "%d" ili drugo....
camLocalDirName[5] = NULL; // ('\0')
.......
dano stane myrzima da go probwam
;
#include <string.h>
char camLocalDirName[6];
strncpy (camLocalDirName, key, 5);
camLocalDirName[5] = NULL;
..........
a ako izkash po twoia si na4in
char camLocalDirName[9]; //ako dyljinata na key e 8 simwola (zaradi \0)
sprintf(camLocalDirName, "%s", key); // ako key e chislo izpolzwai "%d" ili drugo....
camLocalDirName[5] = NULL; // ('\0')
.......
dano stane myrzima da go probwam
Допълнение
Фундаменталната ти грешка е, че очакваш щом масива е 5 символа, в него да могат да се отпечатат най-много 5. Тук има два проблема: а) не броиш завършващата всеки низ нула б) на C-то (по-точно на библиотеката, реализираща sprintf) не му пука колко ти е голям масива - взима се само началото и се пише колкото има за писане. Тоест, в твоят случай се получава омазване на паметта. Ако искаш да решиш проблема със sprintf, използвай версията snprintf, в която задаваш колко най-много символи искаш да се отпечатат (брои се и завършващата нула). Като не забравяш, че за всеки низ са нужни n+1 символа (n е дължината, а 1 е за 0-та в края). А и последно - не е нужно да печаташ "\0" накрая - може просто:
char camLocalDirName [6]; snprintf (camLocalDirName, 6, "%s", key);
Успех.
char camLocalDirName [6]; snprintf (camLocalDirName, 6, "%s", key);
Успех.
Редактирано от Masklin на
Re: Помощ! char в C++
char cBack = key[5];
key[5]=0;
_chdir(camLocalDirName);
_mkdir(key);
key[5]=cBack;
Si Vis Pacem, Para Bellum
key[5]=0;
_chdir(camLocalDirName);
_mkdir(key);
key[5]=cBack;
Si Vis Pacem, Para Bellum
Благодаря!
на всички, макар и със закъснение. Този проблем го реших в крайна сметка така:
char camLocalDirName[5]; sprintf(camLocalDirName, "%s", key); camLocalDirName[5]='\0';
на пръвия ред вместо публикувания в първото му съобщение. Така вече е ОК, появи ми се обаче друг сериозен проблем...
char camLocalDirName[5]; sprintf(camLocalDirName, "%s", key); camLocalDirName[5]='\0';
на пръвия ред вместо публикувания в първото му съобщение. Така вече е ОК, появи ми се обаче друг сериозен проблем...
Re: Благодаря!
сериозния проблем най-вероятно идва от "омазването" на паметта, за което беше споменал някой. затова най-добре ползвай snprintf, или копирай символите един по един (за последното не те съветвам).
stoj, ta gledaj
stoj, ta gledaj
wnimanie!!!
eeeh ne se pouchi ot izkazwaniata, ta i az da ti reka
twoia code:
char camLocalDirName[5];
sprintf(camLocalDirName, "%s", key);
camLocalDirName[5]='\0';
ima dwa seriozni problema - camLocalDirName[5] referira pamet izwyn masiwa
camLocalDirName koito se indexira s indexi 0, 1, 2, 3, 4
zabeleji che se broi ot 0 taka che stawat obshto 5 elemnta no poslednia
e s index 4
adresiraneto na element sled poslednia shte dowede do zamazwane na pamet
primerno w steka ako pametta za masiwa e tam ili w segmenta s dannite
ako e statichen...
mnoooogo zle.
syshtoto prawi i sprintf - kazaha ti che toi pishe w tolkowa char-a kolkoto e
stringa deto go sprinntf-wash a ne kolkoto ti se iska na teb
moje da napishesh syshto
sprintf(camLocalDirName, "%*.*s", 5,5, key);
i to sled kato definirash camLocalDirName kato
char camLocalDirName[6];
a predstawiash li si kakwo ako key ne e null-terminated string? kupooon :)
imash dosta da opresnish znaniata si wyrhu masiwi w C i stdlib
wnimawai!!! daje da ne ti grymi sega ne e iasno kakwo shte se poluchi
twoia code:
char camLocalDirName[5];
sprintf(camLocalDirName, "%s", key);
camLocalDirName[5]='\0';
ima dwa seriozni problema - camLocalDirName[5] referira pamet izwyn masiwa
camLocalDirName koito se indexira s indexi 0, 1, 2, 3, 4
zabeleji che se broi ot 0 taka che stawat obshto 5 elemnta no poslednia
e s index 4
adresiraneto na element sled poslednia shte dowede do zamazwane na pamet
primerno w steka ako pametta za masiwa e tam ili w segmenta s dannite
ako e statichen...
mnoooogo zle.
syshtoto prawi i sprintf - kazaha ti che toi pishe w tolkowa char-a kolkoto e
stringa deto go sprinntf-wash a ne kolkoto ti se iska na teb
moje da napishesh syshto
sprintf(camLocalDirName, "%*.*s", 5,5, key);
i to sled kato definirash camLocalDirName kato
char camLocalDirName[6];
a predstawiash li si kakwo ako key ne e null-terminated string? kupooon :)
imash dosta da opresnish znaniata si wyrhu masiwi w C i stdlib
wnimawai!!! daje da ne ti grymi sega ne e iasno kakwo shte se poluchi
Re: wnimanie!!!
Мерси за бележките, за мен са важни - ами аз не съм никакъв специалист по С. Досега съм писала само на VB, а вие по-добре от мен разбирате, че разликата е голяма, особено като трябва да се работи с char. Все пак - не разбирам кое е най-доброто разрешение в случая на моя проблем, ако не искам да използвам basic_str /струва ми се ненужно заради едно такова просто нещо да използвам библиотеката/. За ваша инфо - "key" не е нул-терминейтед стринг /или поне така се показва в Watch, за разлика от другите променливи като path например - там ясно се вижда /0 и продължението след това.../.
Знам, че sprintf копира всички символи и има опасност от омазване в този случай. Тогава следния код не може ли да реши проблема ми:
char camLocalDirName[9]; // - предназначено за целия стринг key + 1 място за 0
sprintf(camLocalDirName, "%s", key);
camLocalDirName[5]='\0';
Е, не е много красиво, но поне няма да се получи намазване на паметта. Ако бъркам, кажете.
Не разбирам много смисъла на твоя съвет /Хелпа за формата на sprintf нещо не изобилства на удобни примери и не мога да разбера добре от описанията как да си конструриам форматиращия стринг, така че да вземе точно 5 символа от key/. Ти ме съветваш за следното:
char camLocalDirName[6];
sprintf(camLocalDirName, "%*.*s", 5,5, key);
така ли? Вероятно този код ще копира точно 5 символа от key в camLocalDirName (въпреки, че не разбирам защо. Точката е нужна, ако трябва да форматираме число с десетичка точка - при стрингове нужна ли е?). Но на мен ми трябва и символа и една нула накрая...
Ако съм много досадна - простете. Вероятно много неща са очевидни на тези, които непрекъснато ги използват, но аз наистина имам тези глупави затруднения...
Междувременно пробвах варианта, който описах по-горе и той работи чудесно! Като прегледах пак всички отговори - едва сега съобразих, че това е варианта, предложен от МисТ, само дето не го разбрах веднага и затова не го изпробвах по-рано.
Знам, че sprintf копира всички символи и има опасност от омазване в този случай. Тогава следния код не може ли да реши проблема ми:
char camLocalDirName[9]; // - предназначено за целия стринг key + 1 място за 0
sprintf(camLocalDirName, "%s", key);
camLocalDirName[5]='\0';
Е, не е много красиво, но поне няма да се получи намазване на паметта. Ако бъркам, кажете.
Не разбирам много смисъла на твоя съвет /Хелпа за формата на sprintf нещо не изобилства на удобни примери и не мога да разбера добре от описанията как да си конструриам форматиращия стринг, така че да вземе точно 5 символа от key/. Ти ме съветваш за следното:
char camLocalDirName[6];
sprintf(camLocalDirName, "%*.*s", 5,5, key);
така ли? Вероятно този код ще копира точно 5 символа от key в camLocalDirName (въпреки, че не разбирам защо. Точката е нужна, ако трябва да форматираме число с десетичка точка - при стрингове нужна ли е?). Но на мен ми трябва и символа и една нула накрая...
Ако съм много досадна - простете. Вероятно много неща са очевидни на тези, които непрекъснато ги използват, но аз наистина имам тези глупави затруднения...
Междувременно пробвах варианта, който описах по-горе и той работи чудесно! Като прегледах пак всички отговори - едва сега съобразих, че това е варианта, предложен от МисТ, само дето не го разбрах веднага и затова не го изпробвах по-рано.
Редактирано от Cилвa на
Re: wnimanie!!!
temata za formatirashtite stringowe w printf etwyrde dylga za da ia pisha tuk
a i shtiah da ia prepisha ot helpa.
moje i "%5.5s" da napishesh sys syshtia uspeh... prosto zwezdichkata
pozwoliawa da zadadesh towa chislo w spisyka na argumentite (kato spazwash reda) w sluchaia ne beshe neoobhodimo, prosto sym go napisal bez da mislia
kolkoto do towa dali e wiarno... ami zawisi edinstweno ot key
ili e null terminated ili si goliama kysmetliika, zashtoto towa koeto poluchawa
printf e edin pointer ... i si chete char-owe (zaradi towa che si mu kazala %s)
dokato stigne do '\0' inache niama spirane nezawisimo kak e definiran key
- kato char key[9] ili pyk camLocalDirName[5] - i w dwata sluchaia se razglejdat
kato char*, po princip printf e s prototip int sprintf( char*, char*, ... )
koeto oznachawa che tia nishto ne znae za razmera na stringowete.
oswen towa sprintf e mnogo bawna funkcia
az bih kazal da pishesh
neshto ot roda na
char sz[5+1];
strncpy(sz, pc, 5);// 5 e broika na simwoli koito da bydat kopirani, nai-mnogo
sz[5]='\0';//za da sme sigurni che ako pc e po-dylyg ili raven na 5 znake
shte si imame 0 nakraia
izobshto na C triabwa mnogo dobre da osyznawash kak raboti f-iata
koiato polzwsh... zashtoto stawa strashno :)
a i shtiah da ia prepisha ot helpa.
moje i "%5.5s" da napishesh sys syshtia uspeh... prosto zwezdichkata
pozwoliawa da zadadesh towa chislo w spisyka na argumentite (kato spazwash reda) w sluchaia ne beshe neoobhodimo, prosto sym go napisal bez da mislia
kolkoto do towa dali e wiarno... ami zawisi edinstweno ot key
ili e null terminated ili si goliama kysmetliika, zashtoto towa koeto poluchawa
printf e edin pointer ... i si chete char-owe (zaradi towa che si mu kazala %s)
dokato stigne do '\0' inache niama spirane nezawisimo kak e definiran key
- kato char key[9] ili pyk camLocalDirName[5] - i w dwata sluchaia se razglejdat
kato char*, po princip printf e s prototip int sprintf( char*, char*, ... )
koeto oznachawa che tia nishto ne znae za razmera na stringowete.
oswen towa sprintf e mnogo bawna funkcia
az bih kazal da pishesh
neshto ot roda na
char sz[5+1];
strncpy(sz, pc, 5);// 5 e broika na simwoli koito da bydat kopirani, nai-mnogo
sz[5]='\0';//za da sme sigurni che ako pc e po-dylyg ili raven na 5 znake
shte si imame 0 nakraia
izobshto na C triabwa mnogo dobre da osyznawash kak raboti f-iata
koiato polzwsh... zashtoto stawa strashno :)
Re: wnimanie!!!
az bih naprawil i:
camLocalDirName[5]='\0';
za da se zastrahowam ako niakyde niakoi reshi che otzad winagi stoi 0
zashtoto strncpy ako prekopira n char-a, niama da sloji i 0 nakraia
camLocalDirName[5]='\0';
za da se zastrahowam ako niakyde niakoi reshi che otzad winagi stoi 0
zashtoto strncpy ako prekopira n char-a, niama da sloji i 0 nakraia
Re: wnimanie!!!
Pravilno :) Sorry, ot godini pozlvam sobstvena dorabotka i izkliuchih :)
za Silveto - krainia kod:
char camLocalDirName[6];
strncpy (camLocalDirName, key, 5);
camLocalDirName[5] = '\0';
za Silveto - krainia kod:
char camLocalDirName[6];
strncpy (camLocalDirName, key, 5);
camLocalDirName[5] = '\0';
Супер сте,
момчета, благодаря ви отново!
Веднага ще направя корекцията - защото наистина иначе не се знае какво би могло да се случи! Като си помисля, направо настръхвам!
Мерси и за търпението ви да обяснявате, защото иначе не виждам как може просто да се преписва код, който не разбирам.
Ех, ще трябва да се стегна наистина, че съм се разглезила с този VB...
Лек ден и весел уикенд на всички!
Веднага ще направя корекцията - защото наистина иначе не се знае какво би могло да се случи! Като си помисля, направо настръхвам!
Мерси и за търпението ви да обяснявате, защото иначе не виждам как може просто да се преписва код, който не разбирам.
Ех, ще трябва да се стегна наистина, че съм се разглезила с този VB...
Лек ден и весел уикенд на всички!