LINUX.ORG.RU

C, ни в зуб ногой.

 


0

3

Надо поправить код под себя, уже убился, то-ли я не понимаю, то-ли лыжи. Гуглить с главным словом «c» ни как не получается.

Извините, что обращаюсь, правлю чей-то дипломный проект под себя. Сам не сишник, и по сям гуглить как-то не получается... (

есть код

....
if(strcmp(strtok(chars_get, ","), "IT_VALUE_IN"))
                goto out_1;

            if((token1 = strtok(NULL, ",")) == NULL)
                goto out_1;

            if((token2 = strtok(NULL, ",")) == NULL)
                goto out_1;
.....
.....
free(chars_get);
return OK_VAL;
out_1:
free(chars_get);
break;
.....

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

            if   (strcmp(strtok(chars_get, ","), "IT_VALUE_IN")) ||    
                 ((token1 = strtok(NULL, ",")) == NULL) || 
                 ((token2 = strtok(NULL, ",")) == NULL)                 
                {free(chars_get);
                 break; }
или токены не получат значения? Но теперь оно требует выражения... Не понимаю.

Научите гуглить по сям...

★★

Последнее исправление: chenger (всего исправлений: 3)

или токены не получат значения?

Насколько помню, || и && выполняют выражения слева направо, поэтому должны присваиваться корректные значения и в таком виде.

Но теперь оно требует выражения... Не понимаю.

Я тоже. Кто чего там хочет таки?

Bfgeshka ★★★★★
()

Не используй strtok(), там внутри static char[]. При попытке использовать с несколькими разными строками или в многопоточном приложении - выгребешь гарантированно. Вместо него - strtok_r()

strcmp() с указателем, выделенным через malloc() тоже может подкинуть сюрприз. strncmp()

anonymous
()

Возьми логическое выражение после if целиком в скобки. А лучше - перепиши всё, наркомания с goto какая-то. Если на token1 строка кончилась, то в token2 не будет записан NULL - и в исходном коде, и в твоём. Подозрительное поведение, надеюсь там по умолчанию что-то лежит. Можно то же самое написать длиннее и понятнее, вроде такого:

int has_it_value_in = !strcmp(strtok(chars_get, ","), "IT_VALUE_IN");

if(has_it_value_in)
{
	token1 = strtok(NULL, ",");
	if(token1)
	{
		token2 = strtok(NULL, ",");
	}
}

free(chars_get);

if(!has_it_value_in ||
	!token1 ||
	!token2)
{
	break;
}
else
{
	return OK_VAL;
}
tim239 ★★
()

Первый пример можно переписать так:

char tokens[3] = { NULL };
int result = FAIL_VAL;

do {
  tokens[0] = strtok(chars_get, ",");
  tokens[1] = strtok(chars_get, ",");
  tokens[2] = strtok(chars_get, ",");
  if (token[0] && token[1] && token[2] &&
     strcmp(tokens[0], "IT_VALUE_IN") == 0)
    result = OK_VAL;
} while (0);
free(chars_get);
return result;
anonymous
()
Ответ на: комментарий от anonymous

Во-первых, зачем тут while(0)?

Во-вторых, tokens тогда уж должен быть char* tokens[3].

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

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

Во-первых, зачем тут while(0)?

Вероятно, анонимус хотел заюзать внутри break для выхода из блока. Разбираться лень.

Скажу только, что судя по коду, это какой-то парсинг, а парсинг на C в норме делать с goto, потому что иначе будет еще более запутанно. Поэтому, ТС, не старайся избежать goto, а старайся, что бы код был понятен в понедельник после пьянки в пятницу :)

Deleted
()

Будет-ли нормально это перепилить для начала хотябы в

Не надо так делать. Сегодня вам пофиг на токены, а завтра понадобятся и придётся опять всё переписывать.

vodz ★★★★★
()

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

Уйди в академический отпуск и потрать следующий год на то, чтобы осилить C.

hateyoufeel ★★★★★
()

strtok вроде как изменяет строку и надо быть внимательным.

ещё есть strtok_r реентерабельная версия.

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

strtok вроде как изменяет строку и надо быть внимательным. ещё есть strtok_r реентерабельная версия.

1. Там стоит free на эту строку, следовательно изменять не страшно.

2. strtok_r вточности также меняет строку, просто не содержит статического указателя внутри функции по запоминанию позиции парсинга.

vodz ★★★★★
()

Перепиши на Расте. Плюс два балла к диплому.

rupert ★★★★★
()

пре:

 do{
         if(strcmp(strtok(chars_get, ","), "IT_VALUE_IN"))
                 break;//toCleaning
         if((token1 = strtok(NULL, ",")) == NULL)
                 break;//toCleaning
         if((token2 = strtok(NULL, ",")) == NULL)
                 break;//toCleaning

         .....
         .....
         //here all prerequisite in state
         free(chars_get);
         return OK_VAL;
 while(false)
 free(chars_get);
 break;
 .....

ps. http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list

pps. тоньше не?

anonymous
()

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

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

то выкинул бы ты весь этот мусор

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

vodz ★★★★★
()

Это мне напоминает авто-сгенерённый код из lex/yacc. Ты точно фиксишь в нужном месте?

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

Это мне напоминает авто-сгенерённый код из lex/yacc

А вы точно его открывали? Вот как раз в lex/yacc - конечные автоматы с таблицами состояний. Где вы в этом коде его узрели?

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

Уйди в академический отпуск и потрать следующий год на то

Тут либо «потрать полгода», либо «потрать полтора года» . Почему все про год говорят в этом контексте? А еще ведь армия есть, так что может быть и 2.5+.

Deleted
()

Больше быдлокода в тред

if (3 != swscanf_s(str,
                   L"%[IT_VALUE_IN],%[^,],%s",
                   tok1, TOK1SIZE,
                   tok2, TOK2SIZE,
                   tok3, TOK3SIZE))
{
  free str;
  log_error(L"Hernia detected!");
  break;
}
thesis ★★★★★
()
Ответ на: комментарий от vodz

Не волнуйся, не только откывал. Оба из них любят сеить goto. Приведённый отрывок очнь не похож на рукописный.

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

Не волнуйся, не только откывал.

Да вот не похоже.

Приведённый отрывок очнь не похож на рукописный.

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

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

эквивалент приведённого отрывка может в своей биографии/анамнезе быть асмо-кодом очередным студентомтехником_кодящим_железо_на_микрухах переписанным на Си - а использование строко-функций -а не прямое байтообмазывание признак того что цей переводчик уже далеко не джун а почти сеньёр. см https://www.gnu.org/fun/jokes/helloworld.html

How the way people code “Hello World” varies depending on their age and job:

High School/Jr. High

10 PRINT «HELLO WORLD» 20 END First year in College

program Hello(input, output) begin writeln('Hello World') end. Senior year in College

(defun hello (print (cons 'Hello (list 'World)))) New professional

#include <stdio.h>

void main(void) { char *message[] = {«Hello », «World»}; int i; for(i = 0; i < 2; ++i) printf(«%s», message); printf(«\n»); } Seasoned professional

#include <iostream.h> #include <string.h> class string { private: int size; char *ptr; public: string() : size(0), ptr(new char('\0')) {} string(const string &s) : size(s.size) { ptr = new char[size + 1]; strcpy(ptr, s.ptr); } ~string() { delete [] ptr; } friend ostream &operator <<(ostream &, const string &); string &operator=(const char *); };

ostream &operator<<(ostream &stream, const string &s) { return(stream << s.ptr); } string &string::operator=(const char *chrs) { if (this != &chrs) { delete [] ptr; size = strlen(chrs); ptr = new char[size + 1]; strcpy(ptr, chrs); } return(*this); } int main() { string str; str = «Hello World»; cout << str << endl; return(0); } System Administrator

#include <stdio.h> #include <stdlib.h> main() { char *tmp; int i=0; /* on y va bourin */ tmp=(char *)malloc(1024*sizeof(char)); while (tmp=«Hello Wolrd»[i++]); /* Ooopps y'a une infusion ! */ i=(int)tmp[8]; tmp[8]=tmp[9]; tmp[9]=(char)i; printf(«%s\n»,tmp); } Apprentice Hacker

#!/usr/local/bin/perl $msg=«Hello, world.\n»; if ($#ARGV >= 0) { while(defined($arg=shift(@ARGV))) { $outfilename = $arg; open(FILE, «>» . $outfilename) || die «Can't write $arg: $!\n»; print (FILE $msg); close(FILE) || die «Can't close $arg: $!\n»; } } else { print ($msg); } 1; Experienced Hacker

#include <stdio.h> #include <string.h> #define S «Hello, World\n» main(){exit(printf(S) == strlen(S) ? 0 : 1);} Seasoned Hacker

% cc -o a.out ~/src/misc/hw/hw.c % a.out Hello, world. Guru Hacker

% cat Hello, world. New Manager (do you remember?)

10 PRINT «HELLO WORLD» 20 END Middle Manager

mail -s «Hello, world.» bob@b12 Bob, could you please write me a program that prints «Hello, world.»? I need it by tomorrow. ^D Senior Manager

% zmail jim I need a «Hello, world.» program by this afternoon. Chief Executive

% letter letter: Command not found. % mail To: ^X ^F ^C % help mail help: Command not found. % damn! !: Event unrecognized % logout Research Scientist

PROGRAM HELLO PRINT *, 'Hello World' END Older research Scientist

WRITE (6, 100) 100 FORMAT (1H ,11HHELLO WORLD) CALL EXIT END

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

Вчера уже уставший был, спать пошел. Требует вот:

error: expected expression before '||' token
             if   (strcmp(strtok(chars_get, ","), "IT_VALUE_IN")) || ((token1 = strtok(NULL, ",")) == NULL) ||

Уйди в академический отпуск и потрать следующий год на то

Тут либо «потрать полгода», либо «потрать полтора года» . Почему все про год говорят в этом контексте? А еще ведь армия есть, так что может быть и 2.5+

Мне это переписать не по учебе нужно, именно для себя. Учить Си полностью как-то нет желания пока, хотел подправить и заставить работать, полезная вроде весч...

chenger ★★
() автор топика
Ответ на: комментарий от chenger
if   (strcmp(strtok(chars_get, ","), "IT_VALUE_IN") || ((token1 = strtok(NULL, ",")) == NULL) ||

Иди проспись.

robus ★★★★★
()

А что в этом коде не работает, что тебя не устраивает? Зачем ты его переделываешь?

Harald ★★★★★
()

не тупой, читать код умею...

не умеешь, видно же что вебмакака

clover
()

Научите гуглить по сям...

Что тебе конкретно нужно нагуглить? man 3 strtok ?

Deleted
()
Последнее исправление: BIGWELLD (всего исправлений: 1)

Не пытайся править чужой код, глупая это затея.

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

Насколько помню, || и && выполняют выражения слева направо, поэтому должны присваиваться корректные значения и в таком виде.

А если забыл, man operator.

u0atgKIRznY5
()

уже выше наверняка сказали : «не используй strtok» и «не используй strtok ни в каком виде».

есть более разумные и безопасные strspn,strcspn,strchr, а ещё есть regex как в классическом posix виде так и в pcre.

для разбора чего-то-там по строчкам неверняка хватит просто регулярок. А если у вас некий файл с конфигом и мутью, то добро пожаловать к bison+flex :-)

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