powered by simpleCommunicator - 2.0.29     © 2024 Programmizd 02
Map
Форумы / C++ [игнор отключен] [закрыт для гостей] / Си объеденить более двух строк.
25 сообщений из 47, страница 1 из 2
Си объеденить более двух строк.
    #40128876
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый вечер.

Вопрос по чистому Си.


Надо сделать строку и текста и нескольких переменных. Типа такой:

"server=127.0.0.1 login=admin"

127.0.0.1 и admin взять из переменных.


так работает:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
...
char str_var[1024] = "server=";
char ip_var[1024] = "127.0.0.1";
char login_var[1024] = "admin";
...


strcat(str_var, ip_var);
strcat(str_var," login=");
strcat(str_var,login_var);


printf("str_var: %s\n", str_var);




Но, можно ли как-то за одну операцию объединить несколько строк, а не использовать много раз strcat?
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40128877
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И второй вопрос, совсем простой.

Присвоить значение строке почему-то получается только при объявлении переменной.

Если написать в функции:

ip_var="127.0.1.1";

то ошибка:

error: incompatible types when assigning to type ‘char[1024]’ from type ‘char *’
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40128886
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Когда-то давным-давно, когда Си был ещё Кернигана и Ричи, в нём существовали
функции concat() и strrcpy(), которые делали в точности то, что ты хочешь. С тех
пор их выпилили.

Теперь рекомендуют С++:
Код: sql
1.
std::string str_var = "server=" + ip_var + " login=" + login_var;


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40128888
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ,

printf выводит по шаблону сколько угодно аргументов, аргументы через запятую после Шаблона
Код: plaintext
1.
printf ("первый-%s второй-%s третий-%s четвертый-%s  пятый-%s", str1, str2, str3, str4, str5);


Код: plaintext
1.
2.
3.
4.
char ip[1024] = "127.0.0.1";
char login[1024] = "admin";

printf ("server=%s login=%s \n", ip, login);
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40128891
wst
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насколько помню, sprintf/snprintf пока еще с нами.
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40128893
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Функциональный стиль в сях не работает обычно. Поэтому композицию нескольких кон-катов не получается
сделать в каком-то достойном и безопасном стиле.

Strcat как результат возвращает первую строку.

Вот вариант.

Код: plaintext
1.
2.
3.
4.
5.
  char str_var[1024] = "server=";
  char ip_var[1024] = "127.0.0.1";
  char login_var[1024] = "admin";

  printf("str_var: %s\n", strcat(strcat(strcat(str_var, ip_var)," login="),login_var));



Но не расслабляйся. Чекай в дебаге с valgrind каждое подобное изменение кода.
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40128894
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот такой месседж должен быть всегда.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
==32152== Memcheck, a memory error detector
==32152== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==32152== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==32152== Command: ./demo
==32152== 
str_var: server=127.0.0.1 login=admin
==32152== 
==32152== HEAP SUMMARY:
==32152==     in use at exit: 0 bytes in 0 blocks
==32152==   total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==32152== 
==32152== All heap blocks were freed -- no leaks are possible
==32152== 
==32152== For lists of detected and suppressed errors, rerun with: -s
==32152== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40128913
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ

Надо сделать строку и текста и нескольких переменных. Типа такой:

"server=127.0.0.1 login=admin"

127.0.0.1 и admin взять из переменных.


Самое простое, выделить приемный буфер в максимальный размер итоговой строки:
Код: plaintext
1.
2.
3.
4.
char buf[1024];
sprintf(buf, "server=%s login=%s", var_server, var_admin);
// и даже более правильно:
snprintf(buf, sizeof(buf), "server=%s login=%s", var_server, var_admin);
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40128935
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

Когда-то давным-давно, когда Си был ещё Кернигана и Ричи, в нём существовали
функции concat() и strrcpy(), которые делали в точности то, что ты хочешь. С тех
пор их выпилили.

Теперь рекомендуют С++:
Код: sql
1.
std::string str_var = "server=" + ip_var + " login=" + login_var;





надо имеено по Си, не С++
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40128936
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alex_Ustinov
Уткъ,

printf выводит по шаблону сколько угодно аргументов, аргументы через запятую после Шаблона
Код: plaintext
1.
printf ("первый-%s второй-%s третий-%s четвертый-%s  пятый-%s", str1, str2, str3, str4, str5);


Код: plaintext
1.
2.
3.
4.
char ip[1024] = "127.0.0.1";
char login[1024] = "admin";

printf ("server=%s login=%s \n", ip, login);



Это-то понятно, но мне надо это склееную строку в коде еще использовать.
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40128940
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mayton
Функциональный стиль в сях не работает обычно. Поэтому композицию нескольких кон-катов не получается
сделать в каком-то достойном и безопасном стиле.

Strcat как результат возвращает первую строку.

Вот вариант.

Код: plaintext
1.
2.
3.
4.
5.
  char str_var[1024] = "server=";
  char ip_var[1024] = "127.0.0.1";
  char login_var[1024] = "admin";

  printf("str_var: %s\n", strcat(strcat(strcat(str_var, ip_var)," login="),login_var));



Но не расслабляйся. Чекай в дебаге с valgrind каждое подобное изменение кода.



Спасибо!

Только на счет valgrind пока ничего не знаю.

Я в блокнотике пишу код, потом копирую на сервер и компию через gcc. Тут наверное про ide какой-нить.

Если как-то по-другому можно, скажите )
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40128941
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl
Уткъ

Надо сделать строку и текста и нескольких переменных. Типа такой:

"server=127.0.0.1 login=admin"

127.0.0.1 и admin взять из переменных.


Самое простое, выделить приемный буфер в максимальный размер итоговой строки:
Код: plaintext
1.
2.
3.
4.
char buf[1024];
sprintf(buf, "server=%s login=%s", var_server, var_admin);
// и даже более правильно:
snprintf(buf, sizeof(buf), "server=%s login=%s", var_server, var_admin);




Функция sprintf используется для записи форматированной строки в буфер символьной строки.



Похоже она как раз склеивает строку и это то что надо, спасибо!

...буду экспериментировать...
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40128958
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ

Только на счет valgrind пока ничего не знаю.

Я в блокнотике пишу код, потом копирую на сервер и компию через gcc. Тут наверное про ide какой-нить.

Если как-то по-другому можно, скажите )

Если ты Windows девелопер то возможно там какие-то другие тулзы но смысл такой-же.

Блокнот или IDE - это вопрос вкусов. Мой пример я написал в редакторе Atom.

То что ты там что-то "копируешь на сервер" - вызывает удивление. В наше время,
в эпоху виртуалок и докеров уже можно весь техно-стек компилляции создать
на рабочем ноутбуке.
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40129013
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткънадо имеено по Си, не С++

Если пишешь для микроконтроллера - проверь-таки наличие в системных библиотеках
функции strrcpy. Если нет - не парься и используй каскад strcat. Низкоуровневая
оптимизация - пока что не твой уровень.
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40129057
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mayton
Уткъ

Только на счет valgrind пока ничего не знаю.

Я в блокнотике пишу код, потом копирую на сервер и компию через gcc. Тут наверное про ide какой-нить.

Если как-то по-другому можно, скажите )

Если ты Windows девелопер то возможно там какие-то другие тулзы но смысл такой-же.

Блокнот или IDE - это вопрос вкусов. Мой пример я написал в редакторе Atom.

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


Понял.

Пока буду в блокноте писать.

Нравится что никаких студий ставить не надо )
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40129059
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov
Уткънадо имеено по Си, не С++

Если пишешь для микроконтроллера - проверь-таки наличие в системных библиотеках
функции strrcpy. Если нет - не парься и используй каскад strcat. Низкоуровневая
оптимизация - пока что не твой уровень.

Это под линукс.

Учту, спасибо )
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40129063
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А все же, как переменной присвоить значение непосредственно в программе?


типа

ip_var="127.0.1.1";


по идее sprintf присваивать может, но это для сложной строчки. А если совсем простое присваивание то как можно сделать?
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40129067
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ, я не знаю что у тебя за компиллятор. Но попробуй так. Должно работать.

Код: plaintext
1.
2.
3.
4.
5.
char *ip_var = "127.0.0.1";

....

ip_var = "192.168.0.1";


Присвоение указателю чего-то. Потом - пере-присвоение.

Но в эти переменные уже нельзя будет конкатенировать потому что алоцировано
ровно столько байтов сколько букв. Ну и +1 символ нуля "\0" (ASCIIZ)
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40129078
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl
Уткъ

Надо сделать строку и текста и нескольких переменных. Типа такой:

"server=127.0.0.1 login=admin"

127.0.0.1 и admin взять из переменных.


Самое простое, выделить приемный буфер в максимальный размер итоговой строки:
Код: plaintext
1.
2.
3.
4.
char buf[1024];
sprintf(buf, "server=%s login=%s", var_server, var_admin);
// и даже более правильно:
snprintf(buf, sizeof(buf), "server=%s login=%s", var_server, var_admin);


Тут sprintf тоже возвращает полезный результат. Можно его взять. Типа.

Код: plaintext
1.
2.
3.
4.
char buf[1024];
 int chars_copied = sprintf(buf, "server=%s login=%s", var_server, var_admin);
// и даже более правильно:
snprintf(buf, chars_copied, "server=%s login=%s", var_server, var_admin);



Еще хорошо-бы избавиться от этого вредного буфера с размером (с хера-ли?) 1024.

Псевдо-код. Печатам в пустоту. С подсчетом. Аллоцируем точный размер. И печатаем второй раз.

Код: plaintext
1.
2.
3.
4.
5.
int chars_copied = fprintf("/dev/null", "server=%s login=%s", var_server, var_admin);
char *dynamic_buf = malloc(chars_copied);
sprintf(dynamic_buf, "........"...);
// используем
free(dynamic_buf);
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40129093
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Еще хорошо-бы избавиться от этого вредного буфера с размером (с хера-ли?) 1024.
А почему бы и нет? Если уверен что можно меньше - делай меньше. А хочешь точности, есть очень простой вариант:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
char *var_format = "...";
char *var_server = "...";
char *var_admin = "...";

size_t out_len = strlen(var_format) + strlen(var_server) + strlen(var_admin) + 1 - 4;
// +1 для конечного нуля,  -4 за счет меток места в формате (%s которые)
char *out = malloc(out_len);
snprintf(out, out_len, var_format, var_server, var_admin);


А если лень перечислять переменные - то массивы указателей и циклы спасут. А еще переменные можно оформить как va_list массив и vsnprintf() всегда к услугам.

А любители С++ с его string+string могут написать себе расширение для strcat():
Код: plaintext
1.
2.
3.
4.
5.
6.
char *strappend(char *s1, char *s2) {
    size_t len = strlen(s1) + strlen(s2) +1;
    char *s1n = realloc(s1, len);
    if (s1n == NULL) return NULL;
    return strcat(s1n, s2);
}



mayton
Псевдо-код. Печатам в пустоту. С подсчетом. Аллоцируем точный размер. И печатаем второй раз.
Ну это уже извращение. Работать будет (если конечно исправить явный баг с именем файла), но извращение.
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40129094
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl

Код: plaintext
1.
char *strappend(char *s1, char *s2) {



Автору можно предложить varargs. Сколько у него там строк? 3 или 4.
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40129095
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonПсевдо-код. Печатам в пустоту. С подсчетом. Аллоцируем точный размер. И печатаем
второй раз.

А что мешает печатать сразу второй раз куда нужно (и это "куда нужно" обычно
таки не буфер в памяти)? Синдром Натальи Хлопотун?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40129097
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

Зришь в корень. Давай (в С++) постулируем алгебру ленивых строк. Что-б не конкатенировались вовсе. Вот такая у меня мысль.
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40129101
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Легко:
Код: sql
1.
2.
std::ostream f("\\\\.\\pipe\\svc") << "server=" << ip_var << " login=" << 
login_var'


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Си объеденить более двух строк.
    #40129103
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот чорт. Я написал в С++?
...
Рейтинг: 0 / 0
25 сообщений из 47, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Си объеденить более двух строк.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]