将Excel列的字母转换为相应的列号

我正在创build一个类来帮助创buildexcel文件(第二个问题)。 我有一个成员函数,在特定的行和列位置创build一个单元格,并将其保存到一个数组。

ExcelSheet::SetValue(int row, int column, std::string szValue) { myWorksheet[row][column] = szValue; } 

但我重载该函数的选项指定列作为一个字母/数字组合,如在Excel中。 我希望能够将诸如“A3”的input转换成第3列第1列,或者将第19列第19列的input转换成第28列。IE,

 ExcelSheet::SetValue(std::string szCell, std::string value) { // search for the alphabetical part of szCell using regex and // convert it to a column number myWorksheet[row][column] = szValue; } 

Excel列模式如下所示:

 A, B, C, D, E... Z (1-26) AA, AB, AC, AD, AE... AZ (27-52) BA, BB, BC, BD, BE... BZ (53-78) ... ZA, ZB, ZC... ZZ AAA, AAB, AAC... AAZ ABA, ABB, ABC... ABZ ... AZA, AZB, AZC... AZZ BAA, BAB, BAC... BAZ ... 

所以我正在考虑某种基于26位的循环可以做到这一点,但我甚至不知道在实现它的时候从哪里开始。

更新:

我几乎有效的代码:它编译,但没有得到正确的一些不明原因的行。

 #include <vector> #include <string> #include <iostream> #include <regex> class VectorClass { std::vector<std::string> vectorString; public: void PrintVector(std::string szValue) { std::string str = "space"; vectorString.push_back(szValue); vectorString.push_back(str); std::cout << "Loop:" << std::endl; for(int i=0; i < vectorString.size(); i++) { std::cout << vectorString[i] << std::endl; } } int GetColumn(std::string szValue) { std::regex rgx("^([a-zA-Z]+)"); std::smatch result; if( regex_search(szValue, result, rgx) ) { std::string szResult = result[0]; int numletters = szResult.length(); const char * colstr = szResult.c_str(); //char colstr[5]; //int numofletters = 0; //for(int n=0;n<szResult.length();n++) { // colstr[n] = szResult.substr(n,1); // numofletters++; //} //char colstr[]="AEF"; int col=0; for(int i=0; i<numletters; i++) { col = 26*col + colstr[i] - 'A' + 1; } return col; //return atoi(szResult.c_str()); } else return -1; } int GetRow(std::string szValue) { std::regex rgx("^[a-zA-Z]+(\d+)$"); std::smatch result; if( regex_search(szValue, result, rgx) ) { std::cout << "test: " << result.size() << std::endl; for(size_t i=0; i<result.size(); ++i) { std::cout << result[i] << std::endl; } std::string szResult = result[0]; return atoi(szResult.c_str()); } else return -1; } }; int main () { VectorClass myclass; //myclass.PrintVector("ship"); std::cout << "A1 = Column " << myclass.GetColumn("A1") << ", Row " << myclass.GetRow("A1") << std::endl; std::cout << "B32 = Column " << myclass.GetColumn("B32") << ", Row " << myclass.GetRow("B32") << std::endl; std::cout << "Z65 = Column " << myclass.GetColumn("Z65") << ", Row " << myclass.GetRow("Z65") << std::endl; std::cout << "AA12 = Column " << myclass.GetColumn("AA12") << ", Row " << myclass.GetRow("AA12") << std::endl; std::cout << "AB366 = Column " << myclass.GetColumn("AB366") << ", Row " << myclass.GetRow("AB366") << std::endl; std::cout << "FAB43 = Column " << myclass.GetColumn("ZAB43") << ", Row " << myclass.GetRow("ZAB43") << std::endl; std::cout << "ZZZ43456 = Column " << myclass.GetColumn("XDE43456") << ", Row " << myclass.GetRow("XDE43456") << std::endl; std::cin.get(); return 0; } 

请注意,一个字符具有ASCII值,您可以从以下列中获取该列:

 char colstr[]="AEF"; int ii, col=0; for(ii=0; ii<3; ii++) { col = 26*col + colstr[ii] - 'A' + 1; } 

有几点需要注意: – 我使用char [] – 一个字符数组来存储string。 这使访问ASCII值微不足道。 – 我将环路硬连接到3 – 如果列标签的长度不同,可能需要解决这个问题 – 单引号中的值“A”是字符“A”,因此ASCII值为65。

编辑:因为你似乎无法获得行值,这是一个非常简单的(C)function,将让你们两个 – 一起显示一些例子的代码。 我无法让你的代码编译 – 显然我没有在我的机器上的库….我假设传递给函数的标签格式正确:只有字母后面只有数字。 它使用toupper()函数处理小写字母(注意 – 这是你的代码没有做的事情)。 我找出最后一个字母的位置,然后对这两个部分进行操作。 我返回rowcol参数指向的位置的行和列的值。

 #include <stdio.h> #include <stdlib.h> void rc(char * cellAddr, int *row, int *col) { int ii=0, jj, colVal=0; while(cellAddr[ii++] >= 'A') {}; ii--; // ii now points to first character of row address for(jj=0;jj<ii;jj++) colVal = 26*colVal + toupper(cellAddr[jj]) -'A' + 1; *col = colVal; *row = atoi(cellAddr+ii); } int main() { int row, col; char cellAddr1[] = "A123"; char cellAddr2[] = "aB321"; char cellAddr3[] = "ABCA6543"; rc(cellAddr1, &row, &col); printf("for %s the row is %d and the column is %d\n", cellAddr1, row, col); rc(cellAddr2, &row, &col); printf("for %s the row is %d and the column is %d\n", cellAddr2, row, col); rc(cellAddr3, &row, &col); printf("for %s the row is %d and the column is %d\n", cellAddr3, row, col); } 

这给了我的输出是:

 for A123 the row is 123 and the column is 1 for aB321 the row is 321 and the column is 28 for ABCA6543 the row is 6543 and the column is 19007 

Java中 ,以防万一有人想要一个Java版本

 import java.util.*; import java.lang.*; import java.io.*; class Ideone { public static void main (String[] args) throws java.lang.Exception { rowColFromA1("C5"); rowColFromA1("$AB123456789"); rowColFromA1("$C$5"); rowColFromA1("C$5"); rowColFromA1("$C5"); rowColFromA1("$D5"); rowColFromA1("$aC$5"); rowColFromA1("$c$5"); rowColFromA1("cBa$99"); rowColFromA1("cBa$"); rowColFromA1("99"); rowColFromA1("$K$34"); } public static int[] rowColFromA1(String a1ref) { int ii=0, jj, colVal=0; char[] cellAddr = a1ref.toCharArray(); int[] rowCol = new int[2]; int endOfCol; try { while(cellAddr[ii] >= 'A' || cellAddr[ii] == '$' ) { ii++;}; endOfCol = (cellAddr[ii-1] == '$') ? ii-1 : ii; } catch (ArrayIndexOutOfBoundsException aiobe) { rowCol[0] = 1; rowCol[1] = 1; return rowCol;} // skip $ of col, if any jj = (cellAddr[0] == '$') ? 1 : 0; // ii now points to first character of row address for(;jj<endOfCol;jj++) colVal = 26*colVal + Character.toUpperCase(cellAddr[jj]) -'A' + 1; rowCol[1] = (colVal > 0) ? colVal : 1; int rowVal = 0; for (;ii < cellAddr.length; ii++) rowVal = rowVal * 10 + cellAddr[ii] - '0'; rowCol[0] = (rowVal > 0) ? rowVal : 1; System.out.println("R"+ rowCol[0]+"C"+rowCol[1]); return rowCol; } } 

在线java IDE: http : //ideone.com/69ISK8