Moving array elements in c, is there a better option

I am reading input from a file (line by line). Each line represents the state of the playing field. The following is an example input:

(8,7,1,0,0,0,0, B, B, B, B, B, B, B, B, B, B, B, B, S, S, R, R, G, b, g , g, g, g, g, g, g, b, g, R, s, B, B, B, B, R, s, s, R, B, B, R, s, s, s, r, b , g, b, r, r, r, r, r, r, r, r, r, s) 0

I used fgets() and strtok() to split the string into () , My problem is:

I need the first 6 integers in their individual variables, for example:

 int column = 8 int row = 7 

and so on.

I want to get rid of the last integer at the end of the input - 0 and the characters should be stored in an array, because they represent pieces of the board.

Now I have an array with all integers and characters stored together.

I can iterate through my array and copy the integers into my variables and then add the characters to the new array. But it is inefficient.

Is there any other way to do this?

I used fscanf() , but I don’t know how to split the string using delimiters.

thanks

+4
source share
3 answers

ENABLED ENABLE ONLY

 if (fscanf(FILE_PTR, "(%d,%d,...,%c,%c,%c,...,%c) %*d", &column, &row, ..., &chars[0], &chars[1], ...) == 60) 

or something like that

the specifier %*d discard this input (you do not want the last number)

for characters, indicate pointers to their indices for a pre-distributed array

for ints, specify the variable pointer / ref

Thanks to Jon Leffler for reminding you to check the result of *scanf (number of things read)!

Additional Information

REEDIT no, that was right -

int fscanf ( FILE * stream, const char * format, ... );

format : a C string containing a sequence of characters that control how the characters extracted from the stream are processed:

  • Space character: the function will read and ignore any space characters that appear before the next non-space character (space characters include spaces, newlines and tabs - see isspace). A single space in the format string checks for any number of whitespace characters extracted from the stream (including not a single one).
  • Character without spaces, except for the format specifier (%): Any character that is not a space character (empty, new line or tab) or part of the format specifier (which starts with the% character) causes the next character to be read from the stream, compare it with this character without spaces, and if it matches, it will be discarded and the function will continue to the next format character. If the character does not match, the function does not work, returning and leaving subsequent characters of the stream unread.
  • Format specifiers: the sequence formed by the initial percent sign (%) indicates the format specifier, which is used to indicate the type and format of the data to be extracted from the stream and stored in the places indicated by additional arguments.

Above is a quote from here. I know about hostility towards cplusplus.com, but I do not have access to the standard. feel free to edit if you do

+3
source

I used fgets() and strtok() to split the string into "()"

later

I used fscanf() , but I don’t know how to split the string using delimiters.

I think if strtok() worked for brackets, it would work with commas too.

In addition: you have several options for doing what you want. Without a lot of context, I cannot tell you which one you want, but here we go:

  • Take a pointer to the first non-integer and use it as if it were a pointer to the first element of another array containing only integers. This avoids all copy and / or move operations.

  • Use memcpy() to copy only the necessary parts of the array to another array. memcpy() is usually highly optimized and faster than the naive for-loop-with-assign method.

+1
source

if you have char * , you can think of it as an array or as a string, since the memory layout is the same ...

 char * input = "(8,7,1,0,0,0,b,b,b,b,b,b,b,b,b,b,b,b,s,s,r,r,g,b,r,g,r,r,r,r,b,r,r,s,b,b,b,b,r,s,s,r,b,b,r,s,s,s,r,b,g,b,r,r,r,r,r,r,r,r,r,s) 0"; size_t len = strlen(input); int currentIndex = 0; char * output = calloc(1,len); for (int i = 0 ; i<len ; i++) { if (input[i] == '(' || input[i] == ')' || input[i] == ','|| input[i] == ' ') { continue; } output[currentIndex++] = input[i]; } assert(strlen(output) == 63); //well formatted? char a = output[0]; char b = output[1]; char (* board)[60] = malloc(60); //pointer to array or is it a mal-formed string. memcpy(board, output+2, 60); char last = output[62]; 

the main thing that I would add if you want to use it more as a string, then you need to make array 1 bigger and set board[60] = \0;

0
source

Source: https://habr.com/ru/post/1481777/


All Articles