我在打印数组内容时遇到问题。每次我想打印它们都会出现分段错误(请查看注释代码)。这是为什么?
#include <stdio.h>
int main(int argc, char* argv[])
{
char const* const fileName = argv[1];
FILE* file = fopen(fileName, "r");
char line[256];
char str1[10], str3[10];
int str2[10], str4[10];
while (fgets(line, sizeof(line), file)) {
printf("The Full Line is: %s", line);
sscanf(line,"%s -> %s", str1,str3);
printf("First is: %s \n", str1);
printf("Thirs is : %s\n", str3);
}
fclose(file);
// printf("%s", str1[0]);
// for (int i=0; i<4; i++){
// printf("This is it!!! %s ", str1[i]);
// }
return 0;
}
输入文本文件包含:
main+0x20 -> main+0x10
function1 -> function2+0x20
function2+0x34 -> function3
或更复杂的一个:
Function2+0x22 -> main+0x92
main -> main+0x22
Function2 -> vuln+0x12
main+0x86 -> Function1
main+0x86 -> main+0x92
Function1+0x12 -> Function2+0x22
func1+0x10 -> main+0x76
dummya -> func1+0x10
main+0x6a -> main+0x76
main+0x6a -> func1
main+0x76 -> main+0x86
main+0x22 -> main+0x3a
main+0xa2 -> main+0xae
func1 -> dummya
func1 -> func1+0x10
main+0x92 -> main+0xa2
main+0x3a -> main+0x52
main+0x52 -> main+0x6a
我可以将此值放入2D数组中吗?然后打印出来。如果是的话怎么做?
我想要这样的输出:
Array1[1]= main
Array2[1]=0x20 //in int
Array3[1]=main
Array4[1]=0x10 //in int
Array1[2]=Function1
Array2[2]=0 //in int
Array3[2]=Function2
Array4[2]=0x20 //in int
Array1[3]=Function2
Array2[3]=0x34 //int
Array3[3]=Function3
Array4[3]=0
//Continue until EOF
答案 0 :(得分:3)
使用%s
假设指向char数组结束空符号的指针。但是你给char指的是char。
如果您需要一个符号 - 您应该使用%c
:
printf("%c", str1[0]);
for (int i=0; i<4; i++){
printf("This is it!!! %c ", str1[i]);
}
如果你需要带偏移的字符串 - 你应该使用指针:
printf("%s", &str1[0]);
for (int i=0; i<4; i++){
printf("This is it!!! %s ", &str1[i]);
}
请参阅printf reference。
<强> EDIT1:强>
#include <stdio.h>
#define MAX_LINE_CNT 3
int main(int argc, char* argv[])
{
char const* const fileName = argv[1];
FILE* file = fopen(fileName, "r");
char line[256];
char i, cnt = 0;
char str1[MAX_LINE_CNT][10], str3[MAX_LINE_CNT][10], * tmp;
int arr2[MAX_LINE_CNT], arr4[MAX_LINE_CNT];
while (fgets(line, sizeof(line), file)) {
tmp = strstr(line," -> ");
arr2[cnt] = 0; arr4[cnt] = 0;
sscanf(line,"%[^+ ]%x%*s", str1[cnt],&arr2[cnt]);
sscanf(tmp," -> %[^+ ]%x%*s", str3[cnt],&arr4[cnt]);
//cnt++;
if (++cnt >= MAX_LINE_CNT) break;
}
fclose(file);
for (i = 0; i < cnt; i++) {
printf("Array1[%d] %s \n", i+1, str1[i]);
printf("Array2[%d] %x \n", i+1, arr2[i]);
printf("Array3[%d] %s \n", i+1, str3[i]);
printf("Array4[%d] %x \n", i+1, arr4[i]);
}
return 0;
}
<强> EDIT2:强>
严格建议阅读chux的答案和c / c ++参考,以了解你在做什么以及编译后到底发生了什么。
答案 1 :(得分:2)
每次我想打印它们时都会出现分段错误(请查看注释代码)。那是为什么?
A)代码没有使用保护。请注意,当将数据读入str1
时,如果文本长度超过9,则代码将导致未定义的行为(UB)为str1[10]
,因为字符串最多只能包含9个字符和空字符。 / p>
B)代码未检查sscanf()
的结果。除非扫描了2个字段,否则printf("Thirs is : %s\n", str3);
将导致UB,因为它可以打印未初始化的字符数组。
// problematic code
// text input "function2+0x34 -> function3\n"
while (fgets(line, sizeof(line), file)) {
char str1[10], str3[10];
sscanf(line,"%s -> %s", str1,str3);
printf("First is: %s \n", str1);
printf("Thirs is : %s\n", str3);
如何解决?
A)限制输入目标数组。 9是要读取的最大字符宽度。
sscanf(line,"%9s -> %9s", str1,str3);
B)检查sscanf()
结果
if (sscanf(line,"%9s -> %9s", str1,str3) != 2) {
fprintf(stderr, "Scan failure\n");
return -1;
}
C)请注意,数组str1[]
和其他数组可能太小。根据需要增加。
我可以将此值放入2D数组中吗?然后打印出来。如果是的话怎么办?我想要像...这样的输出。
当然代码可以,但这是另一个需要OP的目标更详细的问题,而且应该是OP首先尝试的问题。
提示:查看sscanf()
格式说明符"%[]"
,"%n"
和"%x"
如果仍有问题,可以使用一些未经测试的代码来扫描str1[]
...
char f [100]; unsigned addr;
int cnt = sscanf(str1,“%99 [^ +] +%x”,f,&amp; addr);
if(cnt == 1)puts(“仅找到第一个字段”);
否则如果(cnt == 2)put(“找到两个字段”);
else put(“意外输入”);
答案 2 :(得分:1)
有许多功能可以检查成功或失败
这将SIZE定义为4,但可以根据需要增加
char str1[SIZE][40]
最多允许4个字符串,每个字符串最多40个字符
第一步是分离两个初始子串。使用扫描集,%39[^-]
最多可扫描39个字符(防止在阵列内存中写入太多字符)并捕获所有不是-
的字符。
strchr
测试子字符串是否包含+
并且子字符串被解析为适当的。
#include <stdio.h>
#include <string.h>
//maximum lines to process
#define SIZE 4
int main(int argc, char* argv[])
{
char line[256];
char str1[SIZE][40], str3[SIZE][40];
char sub1[40], sub3[40];
// char sub1[SIZE], sub3[SIZE]; //mistake on this line
int str2[SIZE], str4[SIZE];
int each = 0;
int result = 0;
int loop = 0;
FILE* file = NULL;
//check for correct arguments
if ( argc != 2) {
printf ( "syntax is program filename\n");
return 1;
}
//check for successful file opening
if ( ( file = fopen(argv[1], "r")) == NULL) {
printf ( "could not open file %s\n", argv[1]);
return 2;
}
while (fgets(line, sizeof(line), file)) {//loop through the file one line at a time
printf("The Full Line is: %s", line);
//sscanf the two sub strings
//sscanf returns number of items scanned so success will be 2
if ( ( result = sscanf(line,"%39[^-] -> %39[^\n]", sub1,sub3)) == 2) {
printf("First is: %s \n", sub1);
printf("Thirs is : %s\n", sub3);
//is there a + in the substring
if ( ( strchr ( sub1, '+')) != NULL) {
//get the two values
if ( ( result = sscanf ( sub1, "%39[^+]+ 0x%x",str1[each], &str2[each])) != 2) {
printf ( "problem parsing sub1 + %s\n", sub1);
continue;
}
}
else {// no +
str2[each] = 0;
//get the one value
if ( ( result = sscanf ( sub1, "%39s",str1[each])) != 1) {
printf ( "problem parsing sub1 %s\n", sub1);
continue;
}
}
//is there a + in the substring
if ( ( strchr ( sub3, '+')) != NULL) {
//if ( ( sub3[strcspn ( sub3, "+")]) < strlen ( sub3)) {
//get the two values
if ( ( result = sscanf ( sub3, "%39[^+]+ 0x%x",str3[each], &str4[each])) != 2) {
printf ( "problem parsing sub3 + %s\n", sub3);
continue;
}
}
else {
str4[each] = 0;
//get the one value
if ( ( result = sscanf ( sub3, "%39s",str3[each])) != 1) {
printf ( "problem parsing sub3 %s\n", sub3);
continue;
}
}
each++;
if ( each >= SIZE) {
// if ( each > SIZE) { //mistake on this line
break;
}
}
else {
printf ( "trouble parsing %s\n", line);
}
}
fclose(file);
for ( loop = 0; loop < each; loop++) {
printf("Array[%d]=%s\n", loop + 1, str1[loop]);
printf("Array[%d]=0x%x\n", loop + 1, str2[loop]);
printf("Array[%d]=%s\n", loop + 1, str3[loop]);
printf("Array[%d]=0x%x\n\n", loop + 1, str4[loop]);
}
return 0;
}