【问题标题】:write multiple files in C iterating over their names在 C 中编写多个文件,遍历它们的名称
【发布时间】:2015-02-20 06:25:30
【问题描述】:

我正在尝试通过迭代、进行一些计算并将索引添加到文件名来编写一堆文件,这是我的代码的一部分(我强调了代码停止编译的位置):

float AltAzCalc(int d, float t, float Lon, float RA, float Dec, float Lat){

    FILE *in;


    -----> char filename[30] = ("hiparcos_horizontal_%lf_%lf.csv",Lon,Lat);
    in = fopen(filename, "w");
    float PI = 3.14159265;// pi
    float G = 6.5949997; 
    float Alt , Az;
    float GST = G + 0.0657098244*d + 1.00273791*t;
    if (GST > 24){
        GST = GST - 24;
    }
    float LST = GST*360/24 + Lon;

    Alt = (180/PI)*(asin(sin(PI*Dec/180)*sin(PI*Lat/180) + cos(PI*Dec/180)*cos(PI*Lat/180)*cos(PI*(LST-RA*360/24)/180)));

    if(sin(PI*(LST-RA*360/24)/180) <= 0){
        Az = (180/PI)*(acos((sin(PI*Dec/180)-(sin(PI*Alt/180)*sin(PI*Lat/180)))/(cos(PI*Alt/180)*cos(PI*Lat/180))));
    }else{
        Az = 360 - (180/PI)*(acos((sin(PI*Dec/180)-(sin(PI*Alt/180)*sin(PI*Lat/180)))/(cos(PI*Alt/180)*cos(PI*Lat/180))));
    }   

    fprintf(in," %lf %lf \n",Alt,Az);

}
int main{
for(int i = -180 ; i < 181 ; i++){
        for(int j = -180 ; j < 181 ; j++){ 
            for(int k = 0; k < 119616 ; k++){

                AltAzCalc(97,9.2,i,AscensionRecta.array[k],Declinacion.array[k],j);



            }

         }
    }
}

我之前使用过这样的语法,只是没有添加任何我想要更改的额外数字,这是一个字符串文字,这就是它所要求的,知道如何解决这个问题吗?

【问题讨论】:

  • 看来你需要sprintf()的帮助。
  • 能否提供一个简单的sintaxis示例?
  • 也许您为了简单起见已对代码进行了精简,但您必须在打开文件时检查错误。 in = fopen(filename,"w"); if(in == NULL) {perror(filename); ... }
  • @WilliamPursell 为什么? (我开始学习 C)
  • 如果fopen失败(例如,文件存在且您没有写权限)并且您不检查,程序将出现段错误。当用户将Segmentation fault 视为错误消息时,远不如hiparcos_horizontal_1_1.csv: permission denied 有用

标签: c string for-loop printf


【解决方案1】:

两件大事:

  1. char filename[30] 的尺寸可能太小,无法容纳名称。
  2. 您需要使用sprintf()/snprintf() 来生成文件名。

值得一提的是,%f 就足够了,建议打印一个浮点值。

做类似(伪代码)

char filename[128] = {0};                                   //allocate enough memory
sprintf(filename, "hiparcos_horizontal_%f_%f.csv",Lon,Lat)); //Added missing semi-colon // use %f, that's enough and recommended, too.

注意:在使用返回的文件指针之前,请务必检查fopen() 的返回值是否成功。

【讨论】:

    【解决方案2】:

    如果你想要一个格式化的字符串,使用snprintf:

    char filename[30];
    
    snprintf(filename, sizeof filename, "hiparcos_horizontal_%f_%f.csv", Lon, Lat);
    

    %f 而不是%lf 打印float

    另请注意(正如 @SouravGhosh 所指出的)[30] 太小而无法隐藏整个文件名。

    【讨论】:

    • 先生,[30] 是不是太小而无法容纳整个文件名?
    • @CarlosSanchez 正确生成文件名后,它成为最大的问题。 YMMV。
    • @SouravGhosh 我吓坏了 Sourav,因为我知道一个事实,这些代码生成的数据远不止我的电脑可以接受,我不擅长处理指针
    【解决方案3】:

    你在这里有一个用括号括起来的逗号表达式。它包含三个子表达式——一个字符串和两个float 变量——它们以从左到右的顺序“计算”,然后最后一个子表达式的结果成为整个括号的结果。因此,正如编译器所说,字符串和Lon 变量的结果(在这种情况下为值)仍未使用。那么Lat的结果不适合初始化char数组。

    编译器不知道你想要一个格式化的字符串,你需要明确地写出来,正如其他人所说:首先你需要为你的文件名准备一个足够长的缓冲区:

    char filename[66];
    

    然后用数据填充它:

    sprintf(filename, "hiparcos_horizontal_%lf_%lf.csv", Lon, Lat);
    

    格式化字符串本身包含 25 个纯字符。假设LonLat 都将转换为不超过20 个字符(但请使用sprintf 描述验证!)总文件名不应超过65 个字符。为 NUL 终止符添加一个,声明中的大小为 66。

    哦,写完文件后别忘了fclose 一个文件!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多