我有以下工作代码;它接受一个字符串输入作为函数参数,并吐出转换为十进制的相同字符串。
我不打算考虑负输入,但我知道当第一个索引字符是" - "时我可以将布尔标志设置为true。如果该标志切换为true,则取总输出并乘以-1。
无论如何,我很难坚持从这里出发去哪里;我想调整我的代码,以便我可以计算小数位。乘以10并添加下一个数字(在从ASCII值转换该数字后)会产生一个在输出中以十进制显示的整数。对于小于1的数字,这显然不会起作用。我理解为什么(但不是真的如何)确定小数点的位置并且说出#34;对于包含小数点的字符串索引之后的任何事情,以不同的方式做到这一点")。此外,我知道不是乘以10的幂并添加下一个数字,我必须乘以-10的因子,但我不确定这如何适合我现有的代码...
#include <stdio.h>
#include <string.h>
int num = 0;
int finalValue(char *string1) {
int i = 0;
if (string1[i] != '\0') {
if (string1[i]<'0' || string1[i]>'9') {
printf("Sorry, we can't convert this to an integer\n\n");
}
else {
num *= 10;
num += string1[i] - '0';
//don't bother using a 'for' loop because recursion is already sort-of a for loop
finalValue(&string1[i+1]);
}
}
return num;
}
int main(int argc, const char * argv[]) {
printf("string to integer conversion yields %i\n",(finalValue("99256")));
return 0;
}
我对上面的代码进行了一些调整,但它确实有效,但是当涉及小数部分时,它有点难看。由于某种原因,实际的整数输出总是高于放入的字符串...数学在某处是错误的。我通过从最终返回值中减去静态量(并手动乘以10的另一个负幂)来解释这个问题...我想避免这样做,所以任何人都可以看到我的数学/控制流程在哪里出错了?
#include <stdio.h>
#include <string.h>
//here we are setting up a boolean flag and two variables
#define TRUE 1
#define FALSE 0
double num = 0;
double dec = 0.0;
int flag = 0;
double final = 0.0;
double pow(double x, double y);
//we declare our function that will output a DOUBLE
double finalValue(char *string1) {
//we have a variable final that we will return, which is just a combination of the >1 and <1 parts of the float.
//i and j are counters
int i = 0;
int j = 0;
//this will go through the string until it comes across the null value at the very end of the string, which is always present in C.
if (string1[i] != '\0') {
//as long as the current value of i isn't 'null', this code will run. It tests to see if a flag is true. If it isn't true, skip this and keep going. Once the flag is set to TRUE in the else statement below, this code will continue to run so that we can properly convert the decimal characers to floats.
if (flag == TRUE) {
dec += ((string1[i] - '0') * pow(10,-j));
j++;
finalValue(&string1[i+1]);
}
//this will be the first code to execute. It converts the characters to the left of the decimal (greater than 1) to an integer. Then it adds it to the 'num' global variable.
else {
num *= 10;
num += string1[i] - '0';
// This else statement will continue to run until it comes across a decimal point. The code below has been written to detect the decimal point and change the boolean flag to TRUE when it finds it. This is so that we can isolate the right part of the decimal and treat it differently (mathematically speaking). The ASCII value of a '.' is 46.
//Once the flag has been set to true, this else statement will no longer execute. The control flow will return to the top of the function, and the if statement saying "if the flag is TRUE, execute this' will be the only code to run.
if (string1[i+1] == '.'){
flag = TRUE;
}
//while this code block is running (before the flag is set to true) use recursion to keep converting characters into integers
finalValue(&string1[i+1]);
}
}
else {
final = num + dec;
return final;
}
return final;
}
int main(int argc, const char * argv[]) {
printf("string to integer conversion yields %.2f\n",(finalValue("234.89")));
return 0;
}
答案 0 :(得分:1)
我看到你已经使用全局变量正确实现了它。这是有效的,但这里有一个关于如何避免全局变量的想法。
一个非常标准的做法是为递归函数添加参数:
double finalValue_recursive(char *string, int flag1, int data2)
{
...
}
然后将带有附加参数的递归函数包装到另一个函数中:
double finalValue(char *string)
{
return finalValue_recursive(string, 0, 0);
}
将此模板用于代码,您可以通过这种方式实现它(似乎只需要一个附加参数):
double finalValue_recursive(char *s, int pow10)
{
if (*s == '\0') // end of line
{
return 0;
}
else if (*s == '-') // leading minus sign; I assume pow10 is 0 here
{
return -finalValue_recursive(s + 1, 0);
}
else if (*s == '.')
{
return finalValue_recursive(s + 1, -1);
}
else if (pow10 == 0) // decoding the integer part
{
int digit = *s - '0';
return finalValue_recursive(s + 1, 0) * 10 + digit;
}
else // decoding the fractional part
{
int digit = *s - '0';
return finalValue_recursive(s + 1, pow10 - 1) + digit * pow(10.0, pow10);
}
}
double finalValue(char *string)
{
return finalValue_recursive(string, 0);
}
答案 1 :(得分:0)
还要跟踪小数点的出现。
int num = 0;
const char *dp = NULL;
int dp_offset = 0;
int finalValue(const char *string1) {
int i = 0;
if (string1[i] != '\0') {
if (string1[i]<'0' || string1[i]>'9') {
if (dp == NULL && string1[i] == '.') {
dp = string1;
finalValue(&string1[i+1]);
} else {
printf("Sorry, we can't convert this to an integer\n\n");
} else {
} else {
num *= 10;
num += string1[i] - '0';
finalValue(&string1[i+1]);
}
} else if (dp) {
dp_offset = string1 - dp;
}
return num;
}
调用finalValue()
代码后,可以使用dp_offset
的值来调整返回值。由于此工作可能是完整浮点转换的开始,因此dp_offset
的值可以在开始应用于有效数之前添加到指数中。
Consider simplification
//int i = 0;
//if (string1[i] ...
if (*string1 ...
注意:在这里使用递归来查找字符串到int
是一个值得怀疑的方法,特别是因为它使用全局变量来完成工作。一个简单的功能就足够了。像未经测试的代码:
#include <stdio.h>
#include <stdlib.h>
long long fp_parse(const char *s, int *dp_offset) {
int dp = '.';
const char *dp_ptr = NULL;
long long sum = 0;
for (;;) {
if (*s >= '0' && *s <= '9') {
sum = sum * 10 + *s - '0';
} else if (*s == dp) {
dp_ptr = s;
} else if (*s) {
perror("Unexpected character");
break;
} else {
break;
}
s++;
}
*dp_offset = dp_ptr ? (s - dp_ptr -1) : 0;
return sum;
}
答案 2 :(得分:0)
想出来:
#include <stdio.h>
#include <string.h>
//here we are setting up a boolean flag and two variables
#define TRUE 1
#define FALSE 0
double num = 0;
double dec = 0.0;
int flag = 0;
double final = 0.0;
double pow(double x, double y);
int j = 1;
//we declare our function that will output a DOUBLE
double finalValue(char *string1) {
//i is a counter
int i = 0;
//this will go through the string until it comes across the null value at the very end of the string, which is always present in C.
if (string1[i] != '\0') {
double newGuy = string1[i] - 48;
//as long as the current value of i isn't 'null', this code will run. It tests to see if a flag is true. If it isn't true, skip this and keep going. Once the flag is set to TRUE in the else statement below, this code will continue to run so that we can properly convert the decimal characers to floats.
if (flag == TRUE) {
newGuy = newGuy * pow(10,(j)*-1);
dec += newGuy;
j++;
finalValue(&string1[i+1]);
}
//this will be the first code to execute. It converts the characters to the left of the decimal (greater than 1) to an integer. Then it adds it to the 'num' global variable.
else {
num *= 10;
num += string1[i] - '0';
// This else statement will continue to run until it comes across a decimal point. The code below has been written to detect the decimal point and change the boolean flag to TRUE when it finds it. This is so that we can isolate the right part of the decimal and treat it differently (mathematically speaking). The ASCII value of a '.' is 46.
//Once the flag has been set to true, this else statement will no longer execute. The control flow will return to the top of the function, and the if statement saying "if the flag is TRUE, execute this' will be the only code to run.
if (string1[i+1] == 46){
flag = TRUE;
finalValue(&string1[i+2]);
}
//while this code block is running (before the flag is set to true) use recursion to keep converting characters into integers
finalValue(&string1[i+1]);
}
}
else {
final = num + dec;
return final;
}
return final;
}
int main(int argc, const char * argv[]) {
printf("string to integer conversion yields %.2f\n",(finalValue("234.89")));
return 0;
}