在碳计算值单元格转换器 [英] Calc cell convertor in C
问题描述
我学习C和我写了一个简单的程序(只是晒黑)。在输入你传递两个参数(行和列)和输出你会得到一个计算(或Excel)code这个小区。
例如:
I'm learning C and I have written a simple program (just a tanning). On input you pass two arguments (row and column) and output you get a Calc (or Excel) code for this cell. For example:
Input: 3 1 Output: A3
Input: 1 27 Output: AA1
在code:
#include <stdio.h>
char kol[7] = "";
unsigned int passes=0, nr;
int powa(unsigned int lv)
{
if(passes < nr)
{
if(kol[lv] == '\0')
{
kol[lv] = 'A';
kol[lv+1] = '\0';
} else
{
kol[lv]++;
if(kol[lv] == 'Z'+1)
{
kol[lv] = 'A';
powa(lv+1);
return 0;
}
}
passes++;
if(lv != 0)
{
powa(lv-1);
} else
{
powa(lv);
}
}
}
int main(void)
{
unsigned int wier;
int i, len=0;
scanf("%u %u", &wier, &nr);
powa(0);
while(kol[len] != '\0')
{
len++;
}
for(i=len-1;i>=0;i--)
{
putchar(kol[i]);
}
printf("%u", wier);
return 0;
}
但是,如果我通过在一个较大的值(如3亿),我得到一个分段错误。为什么呢?
But if I pass in a larger value (such as 300000000) I get a segmentation fault error. Why?
推荐答案
您与递归实验?我不认为我会使用递归的解决方案。你应该不会因为你是用尽可能多的全局变量,无论是。
Are you experimenting with recursion? I don't think I'd be using a recursive solution. You should probably not be using as many global variables as you are, either.
假设递归是至关重要的,那么在外形,我想我会希望使用的解决方案,例如:
Assuming recursion is crucial, then in outline, I think I'd expect to use a solution such as:
char *powa(unsigned int code, char *buffer)
{
unsigned int div = code / 26;
unsigned int rem = code % 26;
if (div > 0)
buffer = powa(div - 1, buffer);
*buffer++ = rem + 'A';
*buffer = '\0';
return buffer;
}
int main(void)
{
char buffer[32];
unsigned int col, row;
printf("Enter column and row numbers: ");
if (scanf("%u %u", &col, &row) == 2)
{
if (col == 0 || row == 0)
fprintf(stderr, "Both row and column must be larger than zero"
" (row = %u, col = %u)\n", row, col);
else
{
char *end = powa(col-1, buffer);
snprintf(end, sizeof(buffer) - (end - buffer), "%u", row);
printf("Col %u, Row %u, Cell %s\n", col, row, buffer);
}
}
return 0;
}
请注意,修订后的 POWA()
它已被格式化的数据的结尾,则返回一个指向空。从理论上讲,我应该检查从的snprintf()
,以确保没有缓冲区溢出的回报。 由于我现在已经编这一点,并测试并修正它(修正是更换递归调用 ...假...
无效C,你可以告诉我没有这个编制,但 POWA(DIV,缓冲区)
与 POWA(DIV - 1,缓冲区)
,需要一个改变,因为计算需要处理的0与1为起点计算。递归方案似乎更简单,我(一个递归调用,而不是他们三个在code)
Note that the revised powa()
returns a pointer to the null at the end of the data it has formatted. Theoretically, I should check the return from snprintf()
to ensure no buffer overflow. Since I have now compiled this, and tested and corrected it (the correction being to replace the recursive call ...bogus...
is not valid C, you can tell I've not compiled this, butpowa(div, buffer)
with powa(div - 1, buffer)
, a change necessary because the calculation needs to deal with 0 versus 1 as the starting point for counting. The recursion scheme seems simpler to me (a single recursive call instead of three of them in your code).
Enter column and row numbers: 13 27
Col 13, Row 27, Cell M27
Enter column and row numbers: 27 13
Col 27, Row 13, Cell AA13
Enter column and row numbers: 30000000 128
Col 30000000, Row 128, Cell BMPVRD128
Enter column and row numbers: 300000000 128
Col 300000000, Row 128, Cell YFLRYN128
下面是code来处理扫描和格式化从code以上而得:
Here is code to handle both scanning and formatting derived from the code above:
/*
** Convert column and row number into Excel (Spreadsheet) alphanumeric reference
** 1,1 => A1
** 27,1 => AA1
** 37,21 => AK21
** 491,321 => RW321
** 3941,87 => EUO87
** From StackOverflow question 7651397 on 2011-10-04:
** http://stackoverflow.com/questions/7651397/calc-cell-convertor-in-c
*/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
extern unsigned xl_row_decode(const char *code);
extern char *xl_row_encode(unsigned row, char *buffer);
static char *xl_encode(unsigned row, char *buffer)
{
unsigned div = row / 26;
unsigned rem = row % 26;
if (div > 0)
buffer = xl_encode(div-1, buffer);
*buffer++ = rem + 'A';
*buffer = '\0';
return buffer;
}
char *xl_row_encode(unsigned row, char *buffer)
{
return(xl_encode(row-1, buffer));
}
unsigned xl_row_decode(const char *code)
{
unsigned char c;
unsigned r = 0;
while ((c = *code++) != '\0')
{
if (!isalpha(c))
break;
c = toupper(c);
r = r * 26 + c - 'A' + 1;
}
return r;
}
static const struct
{
unsigned col;
unsigned row;
char cell[10];
} tests[] =
{
{ 1, 1, "A1" },
{ 26, 2, "Z2" },
{ 27, 3, "AA3" },
{ 52, 4, "AZ4" },
{ 53, 5, "BA5" },
{ 676, 6, "YZ6" },
{ 702, 7, "ZZ7" },
{ 703, 8, "AAA8" },
{ 728, 9, "AAZ9" },
};
enum { NUM_TESTS = sizeof(tests) / sizeof(tests[0]) };
int main(void)
{
char buffer[32];
int pass = 0;
for (int i = 0; i < NUM_TESTS; i++)
{
char *end = xl_row_encode(tests[i].col, buffer);
snprintf(end, sizeof(buffer) - (end - buffer), "%u", tests[i].row);
unsigned n = xl_row_decode(buffer);
const char *pf = "FAIL";
if (tests[i].col == n && strcmp(tests[i].cell, buffer) == 0)
{
pf = "PASS";
pass++;
}
printf("%s: Col %3u, Row %3u, Cell (wanted: %-8s vs actual: %-8s) Col = %3u\n",
pf, tests[i].col, tests[i].row, tests[i].cell, buffer, n);
}
if (pass == NUM_TESTS)
printf("== PASS == %d tests OK\n", pass);
else
printf("!! FAIL !! %d out of %d failed\n", (NUM_TESTS - pass), NUM_TESTS);
return (pass == NUM_TESTS) ? 0 : 1;
}
这篇关于在碳计算值单元格转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!