2012-05-15 30 views
7

Tôi có một giá trị mà tôi đã đọc từ một tệp và được lưu trữ dưới dạng char *. Giá trị là số tiền, #. ##, ##. ##, hoặC###. ##. Tôi muốn chuyển đổi char * thành một số tôi có thể sử dụng trong tính toán, tôi đã thử atof và strtod và họ chỉ cho tôi số lượng rác. Cách chính xác để làm điều này là gì, và tại sao cách tôi làm sai?Chuyển đổi char * để thả nổi hoặc gấp đôi

Đây thực chất là những gì tôi đang làm, chỉ giá trị char * được đọc từ một tệp. Khi tôi in ra các biến temp và ftemp chúng chỉ là rác, số âm khổng lồ.

Một Edit:

Tôi đang chạy một cách chính xác này trong gcc

#include <stdio.h> 
int main() 
{ 
char *test = "12.11"; 
double temp = strtod(test,NULL); 
float ftemp = atof(test); 
printf("price: %f, %f",temp,ftemp); 
return 0; 

}

và đầu ra của tôi là giá cả: 3344336,000000, 3344336,000000

Edit: Đây là mã của tôi

if(file != NULL) 
    { 
     char curLine [128]; 
     while(fgets(curLine, sizeof curLine, file) != NULL) 
     {    
      tempVal = strtok(curLine,"|");   
      pairs[i].name= strdup(tempVal); 
      tempVal = strtok(NULL,"|"); 
      pairs[i].value= strdup(tempVal); 
      ++i; 
     } 
     fclose(file); 
    } 

    double temp = strtod(pairs[0].value,NULL); 
    float ftemp = atof(pairs[0].value); 
    printf("price: %d, %f",temp,ftemp); 

tập tin đầu vào của tôi là cái tên rất đơn giản, các cặp giá trị như thế này:

NAME|VALUE 
NAME|VALUE 
NAME|VALUE 

với giá trị là đô la số tiền

SOLVED: Cảm ơn tất cả các bạn, tôi đã sử dụng% d thay vì% f và didn' t có các tiêu đề phù hợp.

+4

Sự cố phải ở một nơi khác, mã bạn đăng hoàn toàn hợp lệ và hoạt động. Vui lòng cho chúng tôi biết cách bạn đọc tệp của mình. –

+0

1. 'atof' trả về' double': http://pubs.opengroup.org/onlinepubs/007904875/functions/atof.html – ArjunShankar

+0

2. '% d' là số nguyên. Sử dụng '% f'. – ArjunShankar

Trả lời

21

Bạn đang thiếu bao gồm: #include <stdlib.h>, do đó GCC tạo khai báo ngầm là atofatod, dẫn đến giá trị rác.

Và trình định dạng định dạng cho đôi là %f, không phải %d (dành cho số nguyên).

#include <stdlib.h> 
#include <stdio.h> 

int main() 
{ 
    char *test = "12.11"; 
    double temp = strtod(test,NULL); 
    float ftemp = atof(test); 
    printf("price: %f, %f",temp,ftemp); 
    return 0; 
} 
/* Output */ 
price: 12.110000, 12.110000 
+1

+1. Đúng. Đây là vấn đề. [trước khi chỉnh sửa OP, thực tế có ba vấn đề] – ArjunShankar

1

Mã do bạn đăng là chính xác và phải có hiệu quả. Nhưng hãy kiểm tra chính xác những gì bạn có trong số char*. Nếu giá trị chính xác lớn để được biểu diễn, hàm sẽ trả về một số dương hoặc âm HUGE_VAL. Kiểm tra những gì bạn có trong số char* so với các giá trị tối đa mà floatdouble có thể đại diện trên máy tính của bạn.

Kiểm tra this page for strtod referencethis page for atof reference.

Tôi đã thử ví dụ bạn cung cấp trong cả Windows và Linux và nó hoạt động tốt.

+1

Theo: http://pubs.opengroup.org/onlinepubs/007904875/functions/atof.html (được căn chỉnh với tiêu chuẩn C): "Nếu giá trị không thể được biểu diễn , hành vi không xác định. " – ArjunShankar

+0

Các giá trị nhỏ hơn nhiều so với loại biến thể tối đa có thể biểu thị, giá trị lớn nhất tôi có là 120,55. – Andrew

+0

@George: không sử dụng cplusplus.com. Nó đầy lỗi. Cả 'atof' lẫn' strtod' đều không trả về HUGE_VAL trong trường hợp tràn. Theo [cppreference] (http://en.cppreference.com/w/c/string/byte/atof), giá trị trả về là không xác định. –

0
printf("price: %d, %f",temp,ftemp); 
       ^^^ 

Đây là vấn đề của bạn. Vì các đối số là loại doublefloat, bạn nên sử dụng %f cho cả hai (vì printf là hàm variadic, ftemp sẽ được thăng cấp thành double).

%d hy vọng đối số tương ứng là loại int, không phải double.

Các chức năng biến thể như printf không thực sự biết các loại đối số trong danh sách đối số biến; bạn phải nói điều đó với công cụ chuyển đổi. Vì bạn đã nói với printf rằng đối số đầu tiên được cho là int, printf sẽ lấy sizeof (int) byte tiếp theo từ danh sách đối số và diễn giải nó dưới dạng giá trị số nguyên; do đó là số rác đầu tiên.

Bây giờ, nó gần như đảm bảo rằng sizeof (int) < sizeof (double), vì vậy khi printf lấy sizeof (double) byte kế tiếp từ danh sách đối số, nó có thể bắt đầu với các byte giữa temp, chứ không phải là byte đầu tiên của ftemp; do đó là số rác thứ hai.

Sử dụng %f cho cả hai.

Các vấn đề liên quan