我想做兩件事:
1)
char *myStr = "2 1 3 2 5 2 5 4 6 1 6 2 7 1 7 3 7 4 8 1 ";
目標是讓我的字串成為這種形式
2 1
3 2
5 2
...
...
依此類推,直到字串結束。
2) 對于這樣的字串,我想將這些值以 myArr[0][0] = 2, myArr[0][1] = 1, myArr[1][0] = 3 的形式放入二維陣列中, myArr[1][1] = 2, 依此類推。
我首先嘗試使用 strtok 但我認為它不合適,因為分隔符不足以解決這個問題然后通過逐字符迭代來拆分但到目前為止我不知道該怎么做:
const char * separator = " "
char * strToken = strtok ( out, separator );
while ( strToken != NULL ) {
printf ( "%s\n", strToken);
strToken = strtok ( NULL, separator);
}
我得到了什么:
2
1
3
2
5
2
5
4
6
1
6
2
7
1
7
3
7
4
8
1
uj5u.com熱心網友回復:
在 C 語言中,試圖讓事情變小是很誘人的,但有時以更長的方式做事情會更清楚。
在這種情況下,您正在嘗試制作自定義決議器。有幾種不同復雜程度的方法可以做到這一點,但我將描述一種簡單的自上而下的方法,從輸入字串到整數值的 2D 排列。
您需要跟蹤掃描字串的距離,以及添加到二維陣列的位置。我假設這些長度不變,如果需要,您可以使它們動態化。
char * myStrPtr = myStr;
int myArr[NUM_PAIRS][2];
int myArrIdx = 0;
你想要的基本操作是掃描一個數字,然后跳過它后面的空格。這是一個功能。它獲取字符指標和指向整數的指標,然后回傳指向下一個數字的指標(跳過錯誤檢查)。
char * getInt(char * myStrPtr, int * i) {
char *myEndPtr = NULL;
*i = strtol(myStrPtr, &myEndPtr, 0);
// Error if myEndPtr == myStrPtr. Skip spaces now.
while (isspace(myEndPtr)) {
myEndPtr ;
}
return myEndPtr;
}
你想一次掃描 2 個數字,所以這里有一個函式可以做到這一點。它采用字符指標和一維int陣列,并回傳新的字符指標。
char * get2Ints(char * myStrPtr, int[2]) {
char *myEndPtr = NULL;
// Skipping check for end of string.
myEndPtr = getInt(myStrPtr, &int[0]);
// Error if myEndPtr == myStrPtr, skipping that check.
// Comments above apply here.
myEndPtr = getInt(myStrPtr, &int[1]);
return myEndPtr;
}
最后,您想掃描字串中的所有對。我假設對的數量是已知的,否則你會先計算它們并為它們分配一個陣列,或者使用鏈表來存盤它們。
for (myArrIdx = 0; myArrIdx < NUM_PAIRS; myArrIdx ) {
char * myEndPtr = get2Ints(myStrPtr, myArr[myArrIdx]);
// Error if myArrPtr == myEndPtr.
myStrPtr = myEndPtr;
}
應該這樣做。
uj5u.com熱心網友回復:
有一種方法可以將數字存盤在一維陣列中,并通過將它們轉換為二維陣列來顯示它們。它不需要依賴于列數的存盤程序。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NROW 10
#define NCOL 2
int main()
{
char *myStr = "2 1 3 2 5 2 5 4 6 1 6 2 7 1 7 3 7 4 8 1 ";
const char * separator = " ";
char * strToken;
char *out;
char *end;
/* 1D array */
int arrBuf[NROW*NCOL];
/* 2D array */
int (*myArr)[NCOL] = (int(*)[NCOL])arrBuf;
int i;
out = strdup(myStr);
/* Store numbers as 1D array */
strToken = strtok ( out, separator );
for (i = 0; i < NROW*NCOL && strToken != NULL ; i ) {
arrBuf[i] = (int)strtol(strToken, &end, 10);
strToken = strtok ( NULL, separator);
}
/* Display numbers as 2D array */
for (i = 0; i < NROW; i ) {
printf("%d %d\n", myArr[i][0], myArr[i][1]);
}
free(out);
return 0;
}
uj5u.com熱心網友回復:
用 . 決議事物strtol。以下是極其脆弱的,依賴于精確的輸入,但它給出了總體思路:
#include <ctype.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
int
main(void)
{
char myStr[] = "2 1 3 2 5 2 5 4 6 1 6 2 7 1 7 3 7 4 8 1 ";
int arr[10][2];
char *t = myStr;
int (*a)[2] = arr;
while( t < myStr sizeof myStr && *t ){
char *end;
a[0][0] = strtol(t, &end, 10);
assert(isspace(*end));
a[0][1] = strtol(end 1, &end, 10);
assert(isspace(*end));
*end = '\n';
t = end 1;
a = 1;
}
printf("%s", myStr);
for( int i = 0; i < 10; i = 1 ){
printf("%d, %d\n", arr[i][0], arr[i][1]);
}
}
uj5u.com熱心網友回復:
我首先嘗試使用 strtok 但我認為它不合適,因為分隔符不足以解決這個問題
這不是使用strtok. 的問題strtok是它必須用空終止字符覆寫定界符,以便各個欄位成為以空字符終止的字串。但是,myStr是指向字串文字的指標,您不能修改它。
因此,如果要使用strtok,則必須將字串文字復制到可寫的記憶體緩沖區,或者myStr不宣告為指向字串文字的指標,而是宣告為可寫char陣列,如下所示:
char myStr[] = "2 1 3 2 5 2 5 4 6 1 6 2 7 1 7 3 7 4 8 1 ";
這是一個使用的解決方案strtok:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_ROWS 100
#define COLS_PER_ROW 2
int main( void )
{
char myStr[] = "2 1 3 2 5 2 5 4 6 1 6 2 7 1 7 3 7 4 8 1 ";
const char delimiters[] = " ";
char myArr[MAX_ROWS][COLS_PER_ROW];
int num_rows = 0;
char *p;
//find first token
p = strtok( myStr, delimiters );
//process one row per loop iteration
for (;;) //infinite loop, equivalent to while(1)
{
//process one column per loop iteration
for ( int i = 0; i < COLS_PER_ROW; i )
{
//determine whether there are more tokens
if ( p == NULL )
{
//print warning message if ran out of tokens in the
//middle of a row, as this should only happen at the
//start of a row
if ( i != 0 )
{
fprintf(
stderr,
"Warning: Ran out of tokens in the middle of "
"a row!\n"
);
}
//we cannot use "break" here, because that would
//only break out of the innermost loop, but we must
//break out of two levels of nested looops
goto break_out_of_nested_loop;
}
//verify that we are not going to write to the array
//out of bounds
if ( num_rows == MAX_ROWS )
{
fprintf(
stderr,
"Too many rows to fit in the array! Stopping..."
);
goto break_out_of_nested_loop;
}
//print warning message and stop parsing if found token
//is larger than one character
if ( strlen( p ) > 1 )
{
fprintf(
stderr,
"Warning: Found token is larger than "
"one character! Stopping...\n"
);
goto break_out_of_nested_loop;
}
//add found character to the array
myArr[num_rows][i] = p[0];
//find next token for next loop iteration
p = strtok( NULL, delimiters );
}
//increase the number of valid rows in the array
num_rows ;
}
break_out_of_nested_loop:
//print the content of the array
for ( int i = 0; i < num_rows; i )
{
for ( int j = 0; j < COLS_PER_ROW; j )
{
printf( "%c ", myArr[i][j] );
}
printf( "\n" );
}
}
該程式具有以下輸出:
2 1
3 2
5 2
5 4
6 1
6 2
7 1
7 3
7 4
8 1
請注意goto,如果可能,通常應避免使用。然而,對于嵌套回圈的跳出,通常沒有更好的選擇,因此一般認為在這種情況下是可以接受的。
由于您只處理單個字符而不是字串,因此您真的不需要strtok. 如果你不需要strtok,那么你也可以使用一個指向字串文字的指標,就像你在問題中定義的那樣:
char *myStr = "2 1 3 2 5 2 5 4 6 1 6 2 7 1 7 3 7 4 8 1 ";
這是一個相應的解決方案:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_ROWS 100
#define COLS_PER_ROW 2
int main( void )
{
char *myStr = "2 1 3 2 5 2 5 4 6 1 6 2 7 1 7 3 7 4 8 1 ";
char myArr[MAX_ROWS][COLS_PER_ROW];
int num_rows = 0;
char *p = myStr;
//process one row per loop iteration
for (;;) //infinite loop, equivalent to while(1)
{
//process one column per loop iteration
for ( int i = 0; i < COLS_PER_ROW; i )
{
//skip all whitespace characters
while ( isspace( (unsigned char)*p ) )
p ;
//determine whether next character is a digit
if ( !isdigit( (unsigned char)*p ) )
{
//check if end of string is reached
if ( *p != '\0' )
{
//unexpected character was found, so print a
//warning message and stop parsing
fprintf(
stderr,
"Warning: Unexpected character found! "
"Stopping...\n"
);
}
//print warning message if ran out of digits in the
//middle of a row, as this should only happen at the
//start of a row
else if ( i != 0 )
{
fprintf(
stderr,
"Warning: Ran out of digits in the middle of "
"a row!\n"
);
}
//we cannot use "break" here, because that would
//only break out of the innermost loop, but we must
//break out of two levels of nested looops
goto break_out_of_nested_loop;
}
//verify that we are not going to write to the array
//out of bounds
if ( num_rows == MAX_ROWS )
{
fprintf(
stderr,
"Too many rows to fit in the array! Stopping..."
);
goto break_out_of_nested_loop;
}
//add found character to the array
myArr[num_rows][i] = p[0];
//go to next character
p ;
//print warning message and stop if next character exists
//and is not a whitespace character (i.e. space,
//newline, etc.)
if ( !isspace( (unsigned char)*p ) )
{
if ( *p != '\0' )
{
fprintf(
stderr,
"Warning: Unspected character found! "
"Stopping...\n"
);
goto break_out_of_nested_loop;
}
}
else
{
//NOTE: This block will be skipped if we
//are already at the end of the string, due to
//the nested "if" statements above
//go to next character
p ;
}
}
//increase the number of valid rows in the array
num_rows ;
}
break_out_of_nested_loop:
//print the content of the array
for ( int i = 0; i < num_rows; i )
{
for ( int j = 0; j < COLS_PER_ROW; j )
{
printf( "%c ", myArr[i][j] );
}
printf( "\n" );
}
}
該程式與第一個程式具有相同的輸出。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/533933.html
標籤:数组C细绳
