#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int Extract(char input[], double output[])
{
int i, j, len;
i=0;
j=0;
len=0;
char s[50];
while(i<strlen(input)-1)
{
if(input[i]==' ') i++;
j=0;
s[0]='\0';
while(input[i]!=',')
{
if(input[i]==' ') i++;
s[j]=input[i];
i++;
j++;
}
s[j]='\0';
i++;
printf("%s - ", s);
output[len]=(double)atof(s);
printf("Element %d: %lf\n", len, output[len]);
len++;
}
printf("%d", len);
return len;
}
int main(){
char s[120]="0.1,0.35,0.05,0.1,0.15,0.05,0.2.";
double v[1000];
int len = Extract(s, v);
int i;
for(i=0; i<len; i++)
{
printf("%d: %lf\n", i, v[i]);
}
return 1;
}
我尝试运行此代码,但是即使编译正确,我也会出现堆栈错误,有人可以帮助我吗? 请注意,该字符串由一些用逗号分隔的十进制数字组成,并且该字符串以。结尾。
更新:也许文件夹中有些脏东西,但是现在我有一个输出:
长度:32
0.1-元素0:0.000000
0.35-元素1:0.000000
0.05-元素2:0.000000
0.1-元素3:0.000000
0.15-元素4:0.000000
0.05-元素5:0.000000
分段错误(核心已转储)
自从我已经创建线程以来,我还能继续利用您的帮助将字符串转换为double,因为atof
正在转换为float,这可能就是它打印所有0.0000的原因了吗?
答案 0 :(得分:0)
我认为我发现了问题:
','
。在输入结束时,您没有','
字符,而是有'.'
,这将导致循环永远持续下去,从而导致段错误。您可以通过将输入的最后一个字符更改为','
来解决此问题。%lf
更改为%.2lf
。这完全取决于您对输入的调节程度。如果可以,请先处理输入,然后再将其输入函数。
让我们知道是否有帮助!
答案 1 :(得分:0)
在这里,我介绍3个代码,第一个解决段错误问题;第二个是对提取功能的详细说明(如所展示);第三,以许多可能的改进形式之一编写的Extract函数示例。
主要的收获应该是始终防止代码中的缓冲区(数组)溢出,并与调试器交朋友。
代码中printf的使用表明没有使用调试器。对任何琐碎的事情(您好,世界吗?)进行编码,都会使调试器的知识更加丰富。了解调试器之类的工具与了解该语言一样重要。
我希望这可以作为指导,甚至可以作为启发。祝您编程愉快。
这是原始代码,其中进行了最少的更改以修复segfault(数组溢出)
int Extract(char input[], double output[])
{
int i, j, len;
i = 0;
j = 0;
len = 0;
char s[50];
while (i<strlen(input) - 1)
{
if (input[i] == ' ') i++;
j = 0;
s[0] = '\0';
/* Primary bug fix; guard against input array overrun *and* check for separator */
while (input[i] && input[i] != ',')
{
if (input[i] == ' ') i++;
s[j] = input[i];
i++;
j++;
}
s[j] = '\0';
/* bug fix; guard against input array overrun when incrementing */
if (input[i]) {
i++;
}
printf("%s - ", s);
output[len] = (double)atof(s);
printf("Element %d: %lf\n", len, output[len]);
len++;
}
printf("%d", len);
return len;
}
这里是对原始代码的批评。
int Extract(char input[], double output[])
{
/* Tedious variable declaration and initialization */
int i, j, len;
i = 0;
j = 0;
len = 0;
/* why not 70? or 420? */
char s[50];
/* This is an exceedingly expensive way to determine end of string. */
while (i<strlen(input) - 1)
{
/* Why test for space? There are no spaces in sample input.
This increment risks overrunning the input array (segfault)
*/
if (input[i] == ' ') i++;
j = 0;
s[0] = '\0';
/* no guard against input array overrun */
while (input[i] != ',')
{
/* Why test for space? There are no spaces in sample input.
This increment risks overrunning the input array (segfault)
*/
if (input[i] == ' ') i++;
s[j] = input[i];
i++;
j++;
}
s[j] = '\0';
/* Bug - no guard against input array overrun when incrementing i */
i++;
/* these print statements suggest someone is NOT using a debugger - major fail if so. */
printf("%s - ", s);
output[len] = (double)atof(s);
printf("Element %d: %lf\n", len, output[len]);
len++;
}
/* again, this is easily seen in the debugger. Use the debugger. */
printf("%d", len);
return len;
}
最后,另一种具有某些(樱桃选择)约定的摘录。
int Extract(double* output, const int output_max, const char* input, const char separator)
{
/* declare variables in the scope they're needed and ALWAYS give variables meaningful names */
int input_index = 0, output_count = 0;
/* Detect end of string and guard against overrunning output buffer */
while (input[input_index] && output_count < output_max)
{
const int BUFFER_MAX = 50;
/* let the compiler init buffer to 0 */
char buffer[BUFFER_MAX] = { 0 };
int buffer_index = 0;
/* accumulate values into buffer until separator or end of string encountered */
while (input[input_index] && input[input_index] != separator)
{
buffer[buffer_index++] = input[input_index++];
if (buffer_index == BUFFER_MAX) {
/* Overrun, cannot process input; exit with error code. */
return -1;
}
}
/* only convert buffer if it had accumulated values */
if (buffer_index) {
/* note atof will discard, say, a trailing period */
output[output_count++] = atof(buffer);
}
/* Guard against input_index increment causing an array overrun (possible segfault) */
if (input[input_index]) {
input_index++;
}
}
return output_count;
}
int main() {
const int OUTPUT_MAX = 1000;
const char separator = ',';
const char* input = "0.1 ,0.35,0.05,0.1,0.15,0.05,0.2.";
double output[OUTPUT_MAX];
const int num_elems = Extract(output, OUTPUT_MAX, input, separator);
/* print results to stdout */
if (num_elems == -1) {
fprintf(stdout, "\nElement too long to process error\n");
}
else {
fprintf(stdout, "\nTotal number of elements: %d\n\n", num_elems);
for (int i = 0; i < num_elems; i++) {
fprintf(stdout, "Element %d: %lf\n", i, output[i]);
}
}
return num_elems;
}
祝您编程愉快。