我有一個C中的字符串,我從某個算法中獲得。它具有這樣將字符串中的值轉換爲浮點數組
0.100
0.840
0.030
0.460
0.760
-0.090
以及格式數值等
在需要這些數值存儲到一個浮陣列,用於數字處理。我是C新手,發現C中的字符串處理很複雜。任何人都可以告訴我如何實現這一點。
我有一個C中的字符串,我從某個算法中獲得。它具有這樣將字符串中的值轉換爲浮點數組
0.100
0.840
0.030
0.460
0.760
-0.090
以及格式數值等
在需要這些數值存儲到一個浮陣列,用於數字處理。我是C新手,發現C中的字符串處理很複雜。任何人都可以告訴我如何實現這一點。
所有的值都是單個字符串,比如「0.100 0.840 0.030 ...」,還是你有一堆單獨的字符串,比如「0.100」,「0.840」,「0.030」等。如果它們在單個字符串中,它們是否被空格(製表符,空格,換行符)或打印字符(逗號,分號)隔開?你知道你有多少價值(即,你的float數組需要多大)?
要轉換代表一個浮點值翻一番字符串,請使用strtod()
如下:
char valueText[] = "123.45";
char *unconverted;
double value;
value = strtod(valueText, &unconverted);
if (!isspace(*unconverted) && *unconverted!= 0)
{
/**
* Input string contains a character that's not valid
* in a floating point constant
*/
}
閱讀上strtod()
瞭解詳情。 unconverted
將指向未被strtod()
轉換的字符串中的第一個字符;如果它不是空白或0,那麼你的字符串沒有被正確格式化爲浮點值,應該被拒絕。
如果所有的值都在一個字符串中,您將不得不將該字符串拆分爲不同的標記。最簡單的(如果有點不安全)的方式來做到這一點是使用strtok()
:
char input[] = "1.2 2.3 3.4 4.5 5.6 6.7 7.8";
char *delim = " "; // input separated by spaces
char *token = NULL;
for (token = strtok(input, delim); token != NULL; token = strtok(NULL, delim))
{
char *unconverted;
double value = strtod(token, &unconverted);
if (!isspace(*unconverted) && *unconverted != 0)
{
/**
* Input string contains a character that's not valid
* in a floating point constant
*/
}
}
閱讀上strtok()
瞭解詳情。
如果你不知道你有多少值,你需要做一些內存管理。您可以動態地分配使用浮動或malloc()
一些realloc()
初始大小的數組,然後定期用realloc()
擴展它:
#define INITIAL_EXTENT 10
double *array = NULL;
size_t arraySize = 0;
size_t arrayIdx = 0;
char input[] = ...; // some long input string
char *delim = ...; // whatever the delimiter set is
char *token;
/**
* Create the float array at some initial size
*/
array = malloc(sizeof *array * INITIAL_EXTENT));
if (array)
{
arraySize = INITIAL_EXTENT;
}
/**
* Loop through your input string
*/
for (token = strtok(input, delim); token != NULL; token = strtok(NULL, delim))
{
double val;
char *unconverted;
if (arrayIdx == arraySize)
{
/**
* We've reached the end of the array, so we need to extend it.
* A popular approach is to double the array size instead of
* using a fixed extent; that way we minimize the number
* of calls to realloc(), which is relatively expensive.
*
* Use a temporary variable to receive the result; that way,
* if the realloc operation fails, we don't lose our
* original pointer.
*/
double *tmp = realloc(array, sizeof *array * (arraySize * 2));
if (tmp != NULL)
{
array = tmp;
arraySize *= 2;
}
else
{
/**
* Memory allocation failed; for this example, we just exit the loop
*/
fprintf(stderr, "Memory allocation failed; exiting loop\n");
break;
}
}
/**
* Convert the next token to a float value
*/
val = strtod(token, &unconverted);
if (!isspace(*unconverted) && *unconverted != 0)
{
/**
* Bad input string. Again, we just bail.
*/
fprintf(stderr, "\"%s\" is not a valid floating-point number\n", token);
break;
}
else
{
array[arrayIdx++] = val;
}
}
當你用它做不要忘記free()
陣列。
你想要的功能被稱爲fscanf。
/* fscanf example */
/* Stolen from cplusplus.com
Modified by C Ross */
#include <stdio.h>
int main()
{
char str [80];
float f;
FILE * pFile;
pFile = fopen ("myfile.txt","r");
/* Loop over this and add to an array, linked list, whatever */
fscanf (pFile, "%f", &f);
fclose (pFile);
printf ("I have read: %f \n",f);
return 0;
}
假設您的字符串是
char *str;
使用類似:
double d[<enter array size here>];
double *pd = d;
for(char *p = str; p = strchr(p, '\n'); p++, pd++)
{
*p = 0;
*pd = atof(p);
*p = '\n';
}
如果它是一個字符串,首先你需要把它拆分在新行字符(S?)然後你可以使用「atof」stdlib函數從它們中創建浮動數字。像這樣:
使用strtod()
。與atof()
不同,它可以檢測輸入字符串中的錯誤。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char buf[] = "0.100\n0.8foo40\n0.030\n\n\n\n0.460\n0.760bar\n-0.090trash";
char *err, *p = buf;
double val;
while (*p) {
val = strtod(p, &err);
if (p == err) p++;
else if ((err == NULL) || (*err == 0)) { printf("Value: %f\n", val); break; }
else { printf("Value: %f\n", val); p = err + 1; }
}
return 0;
}
strtod()
返回讀取的值,除非出現錯誤。
如果err
指向傳入的字符串,則不能使用字符串,因此在上面的代碼片段中,我增加p以繼續從下一個位置讀取。
如果err
爲NULL或指向一個空字符串,沒有錯誤,所以,在我的片段中,我打印該值並停止循環。
如果err
點某處的字符串(不p
本身,前測試),這是在我的代碼片段,其中的錯誤,字符以上,我知道的東西被讀取,所以我打印出來,集合P一個過去的錯誤和循環。
編輯爲了完整起見,我應該提到的錯誤還沒有的情況下。它可能發生strtod()
讀取一個字符序列(雖然有效)不能用double
表示。在這種情況下,errno
被設置爲ERANGE,並且該值本身是「無意義的」。您應在撥打strtod()
之前將errno
設置爲0,然後在使用返回值之前進行檢查。對於非常小的輸入值(例如「1E-42000」),設置errno
是實現定義的,但返回0(或幾乎爲0)。
我試圖實現這一點,但我每次都得到分段錯誤錯誤。看着它。你有什麼想法可能導致它? – sfactor
段錯在哪裏發生?在閱讀令牌?轉換令牌?擴展數組?分配值?我把這些代碼扔掉了我的頭頂,所以如果有錯誤,我不會感到驚訝,但它有助於確切知道它在哪裏死去。如果你可以通過調試器運行它來找到確切的線路,那會很有幫助。 –