以下代码:
- 干净编译
- 执行所需的功能
- 注意访问数据字符串的正确方法
- 注意头文件的适当用法:
ctype.h和函数:toupper()
- 未使用的变量,如
char tempStr[256]; 以及对该变量的所有引用都将被删除
- 将由于尝试修改只读内存中的数据而导致“段错误”事件
现在是错误代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void LettersToCapital(char **string, size_t size);
void ReadOutAOC(char **string, size_t size);
int main( void )
{
char *canadianProvinces[] =
{
"British Columbia",
"Alberta",
"Saskatchewan",
"Manitoba",
"Ontario",
"Quebec",
"New Brunswick",
"Nova Scotia",
"Prince Edward Island",
"Newfoundland",
"Yukon",
"Northwest Territories",
"Nunavut"
};
size_t numOfCanProv = sizeof(canadianProvinces) / sizeof(canadianProvinces[0]);
printf("\nNumber of Canadian provinces %lu\n", numOfCanProv);
// printing all provinces before conversion
printf("\nBefore \"all to capital conversion\"\n\n");
ReadOutAOC(canadianProvinces, numOfCanProv);
LettersToCapital(canadianProvinces, numOfCanProv);
// Temp(canadianProvinces);
// printing all provinces after conversion
printf("\nAfter \"all to capital conversion\"\n");
ReadOutAOC(canadianProvinces, numOfCanProv);
}
void ReadOutAOC(char **string, size_t size)
{
printf("\n");
for( size_t i = 0; i < size; i++)
printf("String outside the assignment method[%lu]: %s\n", i + 1, string[i] );
}
void LettersToCapital(char **string, size_t size)
{
for( size_t i = 0; i < size; i++)
{
size_t j;
for( j = 0; j < strlen( string[i] ); j++)
{
string[i][j] = (char)toupper( string[i][j] );
}
printf("String inside the assignment method[%lu]: %s\n", i + 1, string[i] );
}
}
运行上述代码会产生以下输出:
Before "all to capital conversion"
String outside the assignment method[1]: British Columbia
String outside the assignment method[2]: Alberta
String outside the assignment method[3]: Saskatchewan
String outside the assignment method[4]: Manitoba
String outside the assignment method[5]: Ontario
String outside the assignment method[6]: Quebec
String outside the assignment method[7]: New Brunswick
String outside the assignment method[8]: Nova Scotia
String outside the assignment method[9]: Prince Edward Island
String outside the assignment method[10]: Newfoundland
String outside the assignment method[11]: Yukon
String outside the assignment method[12]: Northwest Territories
String outside the assignment method[13]: Nunavut
Segmentation fault (core dumped)
使用gdb单步执行程序显示seg fault事件的原因是这一行:
string[i][j] = (char)toupper( string[i][j] );
因为它试图更改只读内存中的值/字节/字符
建议修改数据的定义为:
#define MAX_PROV_NAME_LEN 50
char canadianProvinces[][ MAX_PROV_NAME_LEN ] =
{
"British Columbia",
"Alberta",
"Saskatchewan",
"Manitoba",
"Ontario",
"Quebec",
"New Brunswick",
"Nova Scotia",
"Prince Edward Island",
"Newfoundland",
"Yukon",
"Northwest Territories",
"Nunavut"
};
然后调整其余代码以匹配将解决问题。
更正后的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX_PROV_NAME_LEN 50
void LettersToCapital(char string[][ MAX_PROV_NAME_LEN ], size_t size);
void ReadOutAOC(char string[][ MAX_PROV_NAME_LEN ], size_t size);
int main( void )
{
char canadianProvinces[][ MAX_PROV_NAME_LEN ] =
{
"British Columbia",
"Alberta",
"Saskatchewan",
"Manitoba",
"Ontario",
"Quebec",
"New Brunswick",
"Nova Scotia",
"Prince Edward Island",
"Newfoundland",
"Yukon",
"Northwest Territories",
"Nunavut"
};
size_t numOfCanProv = sizeof(canadianProvinces) / sizeof(canadianProvinces[0]);
printf("\nNumber of Canadian provinces %lu\n", numOfCanProv);
// printing all provinces before conversion
printf("\nBefore \"all to capital conversion\"\n\n");
ReadOutAOC(canadianProvinces, numOfCanProv);
LettersToCapital(canadianProvinces, numOfCanProv);
// Temp(canadianProvinces);
// printing all provinces after conversion
printf("\nAfter \"all to capital conversion\"\n");
ReadOutAOC(canadianProvinces, numOfCanProv);
}
void ReadOutAOC(char string[][ MAX_PROV_NAME_LEN ], size_t size)
{
printf("\n");
for( size_t i = 0; i < size; i++)
printf("String outside the assignment method[%lu]: %s\n", i + 1, string[i] );
}
void LettersToCapital(char string[][ MAX_PROV_NAME_LEN ], size_t size)
{
for( size_t i = 0; i < size; i++)
{
size_t j;
for( j = 0; j < strlen( string[i] ); j++)
{
string[i][j] = (char)toupper( string[i][j] );
}
printf("String inside the assignment method[%lu]: %s\n", i + 1, string[i] );
}
}
运行更正后的代码会产生以下输出:
Number of Canadian provinces 13
Before "all to capital conversion"
String outside the assignment method[1]: British Columbia
String outside the assignment method[2]: Alberta
String outside the assignment method[3]: Saskatchewan
String outside the assignment method[4]: Manitoba
String outside the assignment method[5]: Ontario
String outside the assignment method[6]: Quebec
String outside the assignment method[7]: New Brunswick
String outside the assignment method[8]: Nova Scotia
String outside the assignment method[9]: Prince Edward Island
String outside the assignment method[10]: Newfoundland
String outside the assignment method[11]: Yukon
String outside the assignment method[12]: Northwest Territories
String outside the assignment method[13]: Nunavut
String inside the assignment method[1]: BRITISH COLUMBIA
String inside the assignment method[2]: ALBERTA
String inside the assignment method[3]: SASKATCHEWAN
String inside the assignment method[4]: MANITOBA
String inside the assignment method[5]: ONTARIO
String inside the assignment method[6]: QUEBEC
String inside the assignment method[7]: NEW BRUNSWICK
String inside the assignment method[8]: NOVA SCOTIA
String inside the assignment method[9]: PRINCE EDWARD ISLAND
String inside the assignment method[10]: NEWFOUNDLAND
String inside the assignment method[11]: YUKON
String inside the assignment method[12]: NORTHWEST TERRITORIES
String inside the assignment method[13]: NUNAVUT
After "all to capital conversion"
String outside the assignment method[1]: BRITISH COLUMBIA
String outside the assignment method[2]: ALBERTA
String outside the assignment method[3]: SASKATCHEWAN
String outside the assignment method[4]: MANITOBA
String outside the assignment method[5]: ONTARIO
String outside the assignment method[6]: QUEBEC
String outside the assignment method[7]: NEW BRUNSWICK
String outside the assignment method[8]: NOVA SCOTIA
String outside the assignment method[9]: PRINCE EDWARD ISLAND
String outside the assignment method[10]: NEWFOUNDLAND
String outside the assignment method[11]: YUKON
String outside the assignment method[12]: NORTHWEST TERRITORIES
String outside the assignment method[13]: NUNAVUT