如何在 C 中将值添加到双精度数组
How to add values to a double array in C
我之前写过类似的问题。但是,我有一个错误现在无法解决。
我正在尝试用 C 编写代码,这样如果我有这样的文件 reg2.dat:
5.1 3.5 1.4
4.9 3 1.4
4.7 3.2 1.3
4.6 3.1 1.5
5 3.6 1.4
然后,我可以 1) 确定行数(在本例中为 5),2)确定列数(在本例中为 3),3) 将所有 15 个值写入双精度数组 X。
我的代码可以实现前两个目标。但是,我无法让双精度数组 X 包含值 (5.1、3.5、1.4、4.9、3、1.4、4.7、3.2、1.3、4.6、3.1、1.5、5、3.6、1.4)。我已经坚持了一个星期,并得到了建议,但不幸的是仍然需要更直接的帮助:(
下面是我的完整有序代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int getCol(char *myStr);
int getRow(char *fileName);
int assignX(int nCol, int nRow, double *X, char *fileName);
int main(){
FILE *f;
char myStr[1000];
int strL;
int nCol;
int nRow;
char *fileName = "reg2.dat";
double *X;
f = fopen(fileName, "r");
if (f == NULL) perror ("Error opening file");
else {
if (fgets(myStr, 1000, f) != NULL )
puts(myStr);
fclose(f);
}
strL = strlen(myStr);
nCol = getCol(myStr);
nRow = getRow(fileName);
printf("Sample size and number of predictors are %d and %d respectively.\n", nRow, nCol-1);
X = (double *) malloc(sizeof(double) * (nRow* nCol));
assignX(int nCol, int nRow, double *X, char *fileName);
return 0;
}
不起作用的辅助函数如下...
int assignX(int nCol, int nRow, double *X, char *fileName){
int i=0;
int j;
char string[1000];
FILE *f;
f = fopen(fileName, "r");
while(fgets(string, sizeof string, f) != NULL){
for (j=0; j<nCol; j++){
strcpy(X[i], strtok(string, " "));
i++;
}
}
for (i=0;i<(nRow*nCol);i++){
printf("%d\n", X[i]);
}
return 0;
}
执行工作的辅助函数如下...
int getCol(char *myStr){
int length,i,count=0;
char prev;
length=strlen(myStr);
if(length > 0){
prev = myStr[0];
}
for(i=0; i<=length; i++){
if(myStr[i]==' ' && prev != ' '){
count++;
}
prev = myStr[i];
}
if(count > 0 && myStr[i] != ' '){
count++;
}
return count;
}
int getRow(char *fileName){
char ch;
int count=0;
FILE *f;
f = fopen(fileName, "r");
while(!feof(f)){
ch = fgetc(f);
if(ch == '\n')
{
count++;
}
}
fclose(f);
return count;
}
这是我运行:
时的错误
gcc -ansi -pedantic readReg.c -o readReg -llapack -lblas -lgfortran
错误:
readReg.c: In function ‘main’:
readReg.c:40: error: expected expression before ‘int’
readReg.c: In function ‘assignX’:
readReg.c:55: error: incompatible type for argument 1 of ‘strcpy’
/usr/include/string.h:128: note: expected ‘char * __restrict__’ but argument is of type ‘double’
您是否尝试使用 atof
而不是 strcpy
将您的 char *
值转换为 double
值?
我的意思是改变这个
strcpy(X[i], strtok(string, " "));
至此
X[i] = atof(strtok(string, " "));
这里有一个例子
http://www.tutorialspoint.com/c_standard_library/c_function_atof.htm
更新:
这里你有函数 AssignX 工作(文件中的最后一行 reg2.dat 必须有一个输入(\n
),如果最后一行没有输入程序会崩溃,因为行号将是 4 而不是 5。我建议您检测这种情况以避免程序崩溃 :D)
int assignX(int nCol, int nRow, double *X, char *fileName){
int i=0;
int j;
char string[1000];
char* data = NULL;
FILE *f;
f = fopen(fileName, "r");
while(fgets(string, sizeof(string), f) != NULL){
data = strtok(string, " ");
for (j=0; NULL != data && j<nCol; j++){
if (data[strlen(data) - 1] == '\n')
data[strlen(data) - 1] = '[=10=]';
X[i] = atof(data);
data = strtok(NULL, " ");
i++;
}
}
for (i=0;i<(nRow*nCol);i++){
printf("%f\n", X[i]);
}
return 0;
}
希望对您有所帮助
正如编译器告诉您的那样,这一行是错误的:
strcpy(X[i], strtok(string, " "));
在语法方面,strcpy
的第一个参数需要是 char*
。 X[i]
不是 char*
.
就功能而言,这不是从字符串中提取 double
的方式。您需要使用 atof
或 sscanf
.
这是一个应该可以工作的更新循环:
// Declare this at the start of the function.
char* token;
...
while(fgets(string, sizeof string, f) != NULL)
{
// Use string to start the call to strtok.
token = strtok(string, " ");
// Even though each row should have nCol, be safe
// and make sure that you don't process token if
// it is NULL.
for ( j = 0; j < nCol && token != NULL; j++)
{
X[i] = atof(token);
i++;
// For subsequent calls to strtok, use NULL
// for the first argument.
token = strtok(NULL, " ");
}
}
你可以这样做,这应该会从文件中产生一个双精度数组:
int assignX(double *X, char *fileName){
int i=0;
FILE *f;
f = fopen(fileName, "r");
while(fscanf(f, "%lf", &(X[i])) != EOF)
i++;
}
我之前写过类似的问题。但是,我有一个错误现在无法解决。
我正在尝试用 C 编写代码,这样如果我有这样的文件 reg2.dat:
5.1 3.5 1.4
4.9 3 1.4
4.7 3.2 1.3
4.6 3.1 1.5
5 3.6 1.4
然后,我可以 1) 确定行数(在本例中为 5),2)确定列数(在本例中为 3),3) 将所有 15 个值写入双精度数组 X。
我的代码可以实现前两个目标。但是,我无法让双精度数组 X 包含值 (5.1、3.5、1.4、4.9、3、1.4、4.7、3.2、1.3、4.6、3.1、1.5、5、3.6、1.4)。我已经坚持了一个星期,并得到了建议,但不幸的是仍然需要更直接的帮助:(
下面是我的完整有序代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int getCol(char *myStr);
int getRow(char *fileName);
int assignX(int nCol, int nRow, double *X, char *fileName);
int main(){
FILE *f;
char myStr[1000];
int strL;
int nCol;
int nRow;
char *fileName = "reg2.dat";
double *X;
f = fopen(fileName, "r");
if (f == NULL) perror ("Error opening file");
else {
if (fgets(myStr, 1000, f) != NULL )
puts(myStr);
fclose(f);
}
strL = strlen(myStr);
nCol = getCol(myStr);
nRow = getRow(fileName);
printf("Sample size and number of predictors are %d and %d respectively.\n", nRow, nCol-1);
X = (double *) malloc(sizeof(double) * (nRow* nCol));
assignX(int nCol, int nRow, double *X, char *fileName);
return 0;
}
不起作用的辅助函数如下...
int assignX(int nCol, int nRow, double *X, char *fileName){
int i=0;
int j;
char string[1000];
FILE *f;
f = fopen(fileName, "r");
while(fgets(string, sizeof string, f) != NULL){
for (j=0; j<nCol; j++){
strcpy(X[i], strtok(string, " "));
i++;
}
}
for (i=0;i<(nRow*nCol);i++){
printf("%d\n", X[i]);
}
return 0;
}
执行工作的辅助函数如下...
int getCol(char *myStr){
int length,i,count=0;
char prev;
length=strlen(myStr);
if(length > 0){
prev = myStr[0];
}
for(i=0; i<=length; i++){
if(myStr[i]==' ' && prev != ' '){
count++;
}
prev = myStr[i];
}
if(count > 0 && myStr[i] != ' '){
count++;
}
return count;
}
int getRow(char *fileName){
char ch;
int count=0;
FILE *f;
f = fopen(fileName, "r");
while(!feof(f)){
ch = fgetc(f);
if(ch == '\n')
{
count++;
}
}
fclose(f);
return count;
}
这是我运行:
时的错误gcc -ansi -pedantic readReg.c -o readReg -llapack -lblas -lgfortran
错误:
readReg.c: In function ‘main’:
readReg.c:40: error: expected expression before ‘int’
readReg.c: In function ‘assignX’:
readReg.c:55: error: incompatible type for argument 1 of ‘strcpy’
/usr/include/string.h:128: note: expected ‘char * __restrict__’ but argument is of type ‘double’
您是否尝试使用 atof
而不是 strcpy
将您的 char *
值转换为 double
值?
我的意思是改变这个
strcpy(X[i], strtok(string, " "));
至此
X[i] = atof(strtok(string, " "));
这里有一个例子
http://www.tutorialspoint.com/c_standard_library/c_function_atof.htm
更新:
这里你有函数 AssignX 工作(文件中的最后一行 reg2.dat 必须有一个输入(\n
),如果最后一行没有输入程序会崩溃,因为行号将是 4 而不是 5。我建议您检测这种情况以避免程序崩溃 :D)
int assignX(int nCol, int nRow, double *X, char *fileName){
int i=0;
int j;
char string[1000];
char* data = NULL;
FILE *f;
f = fopen(fileName, "r");
while(fgets(string, sizeof(string), f) != NULL){
data = strtok(string, " ");
for (j=0; NULL != data && j<nCol; j++){
if (data[strlen(data) - 1] == '\n')
data[strlen(data) - 1] = '[=10=]';
X[i] = atof(data);
data = strtok(NULL, " ");
i++;
}
}
for (i=0;i<(nRow*nCol);i++){
printf("%f\n", X[i]);
}
return 0;
}
希望对您有所帮助
正如编译器告诉您的那样,这一行是错误的:
strcpy(X[i], strtok(string, " "));
在语法方面,strcpy
的第一个参数需要是 char*
。 X[i]
不是 char*
.
就功能而言,这不是从字符串中提取 double
的方式。您需要使用 atof
或 sscanf
.
这是一个应该可以工作的更新循环:
// Declare this at the start of the function.
char* token;
...
while(fgets(string, sizeof string, f) != NULL)
{
// Use string to start the call to strtok.
token = strtok(string, " ");
// Even though each row should have nCol, be safe
// and make sure that you don't process token if
// it is NULL.
for ( j = 0; j < nCol && token != NULL; j++)
{
X[i] = atof(token);
i++;
// For subsequent calls to strtok, use NULL
// for the first argument.
token = strtok(NULL, " ");
}
}
你可以这样做,这应该会从文件中产生一个双精度数组:
int assignX(double *X, char *fileName){
int i=0;
FILE *f;
f = fopen(fileName, "r");
while(fscanf(f, "%lf", &(X[i])) != EOF)
i++;
}