C语言字符串初始化错误
在写指针数组题目时,遇到数字转换问题。
问题如下:
将大于0小于1000的阿拉伯数字转换为罗马数字。
表示个位数:I,II,III,IV,V,VI,VII,VIII,IX
表示十位数:X,XX,XXX,XL,L,LX,LXX,LXXX,XC
表示百位数:C,CC,CCC,CD,D,DC,DCC,DCCC,CM
我选择了查表法。
第一次(错误的)代码如下:
#include<stdio.h>
int main()
{
char* a[][10] = { "","I","II","III","IV","V","VI","VII","VIII","IX"//应有逗号
"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC",
"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM" };//将罗马数字储存在字符串数组里。
int n, t;
while (scanf("%d", &n) > 0) {
for (int i = 0, j = 1000; i < 3; ++i, j /= 10) {
t = (n % j) / (j / 10);//t为(j-1)所在数位的数值
printf("%s", a[2 - i][t]);
}
printf("\n");
}
}
编译器可以正常运行但一直在警告。
[Warning] deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
//警告:不推荐从字符串常量转换为’char '[-Wwrite-strings]
为什么呢?
经过查阅资料,我了解到原来char *背后的含义是:给我个字符串,我要修改它。
而理论上,我们传给函数的字面常量是没法被修改的。
所以说,比较合理的办法是把参数类型修改为const char *。
这个类型说背后的含义是:给我个字符串,我只要读取它。
第二次(错误的)代码如下:
#include<stdio.h>
int main()
{
const char* a[][10] = { "","I","II","III","IV","V","VI","VII","VIII","IX"//应有逗号
"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC",
"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM" };//将罗马数字储存在字符串数组里。
int n, t;
while (scanf("%d", &n) > 0) {
for (int i = 0, j = 1000; i < 3; ++i, j /= 10) {
t = (n % j) / (j / 10);
printf("%s", a[2 - i][t]);
}
printf("\n");
}
}
经过测试得到以下数据
1
CXI
9
CXIX
10
CXX
11
CXXI
99
CIX
100
CCX
150
CCLX
999
(null)IX
一开始看到这串数据,我整个人都炸了。
经过多次推理,我坚信我解题的逻辑并没有问题
但我锲而不舍地测试以及学长的帮助下后,代码终于崎岖且正确了。
第三次(正确的)代码如下:
int main()
{
const char* a[][10] = { "","I","II","III","IV","V","VI","VII","VIII","IX"//应有逗号
"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC",
"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM" };//将罗马数字储存在字符串数组里。
int n, t;
while (scanf("%d", &n) > 0) {
if (n < 10)
printf("%s", a[0][n]);
else {
for (int i = 0, j = 1000; i < 3; ++i, j /= 10) {
t = (n % j) / (j / 10);
if (i == 2)
printf("%s", a[2 - i][t]);
else if(t>=1)
printf("%s", a[2 - i][t - 1]);
}
}
printf("\n");
}
}
经过测试代码正确,这说明字符数组存储""是无效的。
但我一直在想,它为什么会是无效的?
看了很多资料,我一直都没有找到答案。
刚刚在优化代码的时候无意中发现了字符串数组a[0][10]"IX"后没有逗号。
第四次(正确的)代码如下:
#include<stdio.h>
int main()
{
const char* a[][10] = { "","I","II","III","IV","V","VI","VII","VIII","IX",
"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC",
"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM" };//将罗马数字储存在字符串数组里。
int n, t;
while (scanf("%d", &n) > 0) {
for (int i = 0, j = 1000; i < 3; ++i, j /= 10) {
t = (n % j) / (j / 10);
printf("%s", a[2 - i][t]);//t为(j-1)所在数位的数值
}
printf("\n");
}
}
没想到一个简简单单的符号引起了一系列的错误。
写代码一定要严谨呀!