【发布时间】:2013-03-18 18:56:06
【问题描述】:
我不明白如何将字符串转换为整数。
这是家庭作业,但是我不想要这个问题的答案——(AKA 正确代码)。如果有人能解释我做错了什么,我将不胜感激! :(
提前致谢!!!
我在 32 位虚拟机上运行 Ubuntu 12.04。
我编译:
nasm -f elf proj2.asm
我链接到:
gcc -o proj2 proj2.o
然后运行它:
./proj2
它显示第一个数字,但当我尝试使用 atoi 时,出现分段错误。
我有一位老师希望我们这样做:
-
从这样排列的文本文件中读取数字:
4 5 4 2 9
(每个整数前都有空格)
按照他的指示:“请务必将七 (7) 个字符读入缓冲区以获取整行。这些是代表数字的五个字符以及字符 CR 和 LF。CR 是十六进制的回车符代码0x0D,LF 是十六进制代码0x0A 的换行符。")
我已删除文件中的空格,并尝试以这种方式读取,但没有帮助。
整数将被读取到堆栈上的一个数组中,最大整数数为 250。但这不是问题:/
以下是我目前的代码。
BUFFERSIZE equ 10
section .data
file_name: db "/home/r/Documents/CS/project2/source/indata.txt", 0x00
file_mode: db "r", 0x00
output: db "%i",0xa
test: db "hello world",10
format: db "%u"
numToRead: db 1
temp: db "hi"
num:db "1",0,0
section .bss
fd: resd 4
length: resd 4
buffer resb BUFFERSIZE
;i was trying to use buffers and just
;read through each character in the string,
;but i couldn't get it to work
section .text
extern fopen
extern atoi
extern printf
extern fscanf
extern fgets
extern getc
extern fclose
global main
main:
;setting up stack frame
push ebp
mov ebp, esp
;opens file, store FD to eax
push file_mode
push file_name
call fopen
;save FD from eax into fd
push eax
mov ebx,eax
mov [fd],ebx
;ebx holds the file descriptor
;push in reverse order
push ebx
push numToRead
push temp
call fgets
push eax
call printf ;prints length (this works, i get a 4.
;Changing the number in the file changes the number displayed.
;I can also read in several lines, just can't get any ints!
;(So i can't do any comparisons or loops :/ )
;i shouldn't need to push eax here, right?
;It's already at the top of the stack from the printf
;pop eax
;push eax
call atoi
;calling atoi gives me a segmentation fault error
push eax
call printf
mov esp,ebp
pop ebp
ret
编辑: 有趣的是,我可以调用 atoi 就好了。那是我尝试的时候
push eax
call atoi
push eax
call printf
我得到分段错误。
【问题讨论】:
-
您的输入文件使用 Windows 样式的 CR-LF 行结尾而不是 Unix/Linux 样式的 LF 行结尾?
-
我相信是这样,我想我不确定有什么区别——它们不一样吗?我不确定它是否相关,但是当我得到输出时(所以如果我在调用 atoi 之前调用 printf),它的形式是:(spaces=_--) -- -_4 所以,我说得很好。转换为整数不起作用:/
-
不,它们不一样。 Windows 样式的文本文件以 2 字符序列 CR 和 LF 结束每一行(C 语法中的
'\r'、'\n')。 Unix 风格的文本文件只使用一个 LF 字符。在 C 中,文本模式 I/O 会根据需要自动将行尾转换为'\n',因此如果您使用getc和fscanf进行输入。但是,如果您要处理的是非本地格式的文件,那就更复杂了。 -
push numToRead推送变量的地址(读取的字节太多!)。你想推送 [contents] - 你必须说“dword”......而且它必须是一个 dword。如果您的讲师说读取 7 个字节,那可能就是您应该做的 - 并确保您的缓冲区有 7 个字节的空间! (将其设为 8 个字节 - 为终止零留出空间)我不确定这是否能解决您使用atoi的问题,但这是我看到的第一个问题。push BUFFERSIZE是正确的 - 它是一个常数,而不是一个变量。 -
Keith:它使用 ascii CR/LF 按照:asciitable.com 我想我对使用 Windows 样式的意思有点困惑:不使用 0xa 和 0xd *尼克斯格式?弗兰克:根据 fgets 页面:cplusplus.com/reference/cstdio/fgets 它说使用 num 作为要复制到 str 中的最大字符数(包括终止的空字符)。我想阅读所有8个?谢谢两位! :)
标签: linux gcc assembly x86 nasm