0

Excelファイルの作成を支援するクラスを作成しています(2番目の質問)。特定の行と列の場所にセルを作成し、それを配列に保存するメンバー関数があります。

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

しかし、Excelのように、列を文字と数字の組み合わせとして指定するオプションを使用して、その関数をオーバーロードしています。「A3」のような入力を行3列1に、またはAB19を行19列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;
}
4

2 に答える 2

4

文字にはASCII値があり、次から列を取得できることに注意してください。

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

注意すべき点がいくつかあります。-文字列を格納するためにchar[]-文字配列-を使用します。これにより、ASCII値へのアクセスが簡単になります。-ループを3にハードワイヤードしました-列ラベルの長さが異なる場合は、それに対処する必要があります-一重引用符で囲まれた値「A」は文字「A」であり、したがってASCII値65です。

編集:行の値を取得するのに問題があるようだったので、ここに両方を取得する非常に単純な(C)関数があります-いくつかの例を示すいくつかのコードと一緒に。コードをコンパイルできませんでした。マシンにライブラリがないようです。関数に渡されるラベルは整形式であると想定しています。文字と数字のみが続きます。関数で小文字を処理しtoupper()ます(注-これはコードが実行しなかったことです...)。最後の文字がどこにあるかを把握し、2つの部分を操作します。rowとパラメータが指す場所の行と列の値を返しcolます。

#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
于 2013-03-06T23:21:12.723 に答える
1

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;
    }

}

オンラインjavaide:http: //ideone.com/69ISK8

于 2014-01-11T03:04:52.067 に答える